feat(chemistry7): Phase 0 — фундамент учебника «Химия 7» (hub + 4 главы)
- миграция 046_chemistry7_hub.sql: родитель chemistry-7 (26§) + 4 ребёнка - chemistry_7_hub.html: emerald-палитра, 4 главы, финал курса (8 боссов, ачивка «Химик 7 класса») - chemistry_7_ch1..ch4.html: каркасы глав на общем движке chem8_engine.js + chem8-textbook.css; PARAS по реальной программе, заглушки-builder'ы - chem7_svg.js: неймспейс Chem7 (надстройка над Chem8), стабы виджетов - chemistry7-page.test.js: jsdom-каркас (6 тестов, все проходят) Содержание § наполняется в фазах 1–4. См. plans/textbooks-7/PLAN_CHEMISTRY_7.md Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
-- Chemistry 7 hub migration.
|
||||
-- Creates chemistry-7 as a full hub textbook (4 chapters) in the style of chemistry-8:
|
||||
-- chemistry-7 (hub, html_path = chemistry_7_hub.html)
|
||||
-- chemistry-7-ch1 (Первоначальные химические понятия, §§1–12) → chemistry_7_ch1.html
|
||||
-- chemistry-7-ch2 (Кислород, §§13–17) → chemistry_7_ch2.html
|
||||
-- chemistry-7-ch3 (Водород, §§18–22) → chemistry_7_ch3.html
|
||||
-- chemistry-7-ch4 (Вода, §§23–26) → chemistry_7_ch4.html
|
||||
--
|
||||
-- Source: Шиманович И. Е., Красицкий В. А., Сечко О. И., Хвалюк В. Н.,
|
||||
-- «Химия 7», Народная асвета, 2023 (2-е изд.). Контент авторский (наш).
|
||||
-- Author left empty per project policy.
|
||||
|
||||
-- 1. Insert the parent chemistry-7 hub row (does not exist yet in the catalog).
|
||||
INSERT OR IGNORE INTO textbooks
|
||||
(slug, subject, grade, title, author, description, html_path, para_count, color, sort_order, is_active, parent_slug)
|
||||
VALUES
|
||||
('chemistry-7', 'chemistry', 7, 'Химия — 7 класс',
|
||||
'',
|
||||
'Первый курс химии: первоначальные химические понятия (вещество, атом, элемент, молекула, формула, валентность, химическая реакция и уравнение), кислород и оксиды, водород, кислоты и соли, вода и основания, реакция нейтрализации. 4 главы, 26 параграфов, 5 лабораторных опытов, 4 практические работы.',
|
||||
'chemistry_7_hub.html', 26, 'emerald', 7, 1, NULL);
|
||||
|
||||
-- 2. Insert the 4 children (chapters).
|
||||
INSERT OR IGNORE INTO textbooks
|
||||
(slug, subject, grade, title, author, description, html_path, para_count, color, sort_order, is_active, parent_slug)
|
||||
VALUES
|
||||
('chemistry-7-ch1', 'chemistry', 7, 'Химия 7 · Первоначальные химические понятия',
|
||||
'',
|
||||
'§§1–12: химия как наука о веществах, чистые вещества и смеси, атомы и химические элементы, относительная атомная масса, молекулы, простые и сложные вещества, химическая формула и относительная молекулярная масса, валентность, физические и химические явления, закон сохранения массы и химические уравнения. Лабораторный опыт 1, практическая работа 1.',
|
||||
'chemistry_7_ch1.html', 12, 'emerald', 1, 1, 'chemistry-7'),
|
||||
('chemistry-7-ch2', 'chemistry', 7, 'Химия 7 · Кислород',
|
||||
'',
|
||||
'§§13–17: воздух как смесь газов, кислород как химический элемент и простое вещество, химические свойства кислорода и горение, оксиды, получение кислорода и катализаторы. Лабораторный опыт 2, практическая работа 2.',
|
||||
'chemistry_7_ch2.html', 5, 'cyan', 2, 1, 'chemistry-7'),
|
||||
('chemistry-7-ch3', 'chemistry', 7, 'Химия 7 · Водород',
|
||||
'',
|
||||
'§§18–22: водород как химический элемент и простое вещество, химические свойства водорода, понятие о кислотах и индикаторах, взаимодействие кислот с металлами и ряд активности, соли как продукты замещения. Лабораторные опыты 3 и 4, практическая работа 3.',
|
||||
'chemistry_7_ch3.html', 5, 'violet', 3, 1, 'chemistry-7'),
|
||||
('chemistry-7-ch4', 'chemistry', 7, 'Химия 7 · Вода',
|
||||
'',
|
||||
'§§23–26: состав, физические и химические свойства воды, основания как сложные вещества и индикаторы, реакция нейтрализации, охрана окружающей среды. Лабораторный опыт 5, практическая работа 4.',
|
||||
'chemistry_7_ch4.html', 4, 'blue', 4, 1, 'chemistry-7');
|
||||
@@ -0,0 +1,106 @@
|
||||
'use strict';
|
||||
/*
|
||||
* Phase 0 jsdom-каркас «Химия 7»: проверяем, что хаб и 4 главы реально
|
||||
* выполняются на движке chem8_engine.js без ошибок скриптов, строится
|
||||
* para-selector с нужным числом карточек, активен первый §, заглушки-builder'ы
|
||||
* рисуют para-hero и кнопку прочтения, а финал-боссы хаба решаются.
|
||||
* Содержание § наполняется в фазах 1–4 — здесь проверяется только каркас.
|
||||
*/
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const { JSDOM, VirtualConsole } = require('jsdom');
|
||||
|
||||
const ROOT = path.join(__dirname, '..', '..');
|
||||
const readF = p => fs.readFileSync(path.join(ROOT, p), 'utf8');
|
||||
const wait = ms => new Promise(r => setTimeout(r, ms));
|
||||
|
||||
/* Инлайним внешние скрипты главы (CDN убираем, api/xp заменяем заглушками). */
|
||||
function buildPage(file) {
|
||||
let html = readF('frontend/textbooks/' + file);
|
||||
const inl = {
|
||||
'/js/biochem-core.js': readF('frontend/js/biochem-core.js'),
|
||||
'/js/chem8_svg.js': readF('frontend/js/chem8_svg.js'),
|
||||
'/js/chem7_svg.js': readF('frontend/js/chem7_svg.js'),
|
||||
'/js/chem8_engine.js': readF('frontend/js/chem8_engine.js')
|
||||
};
|
||||
html = html
|
||||
.replace(/<script defer src="https:\/\/cdn[^"]*"[^>]*><\/script>/g, '')
|
||||
.replace(/<script src="\/js\/api\.js" defer><\/script>/, '<script>window.renderMathInElement=function(){};</script>')
|
||||
.replace(/<script src="\/js\/xp\.js" defer><\/script>/, '');
|
||||
Object.keys(inl).forEach(src => {
|
||||
html = html.replace(new RegExp('<script src="' + src + '" defer><\\/script>'), () => '<script>\n' + inl[src] + '\n</script>');
|
||||
});
|
||||
return html;
|
||||
}
|
||||
|
||||
async function loadDom(file) {
|
||||
const errors = [];
|
||||
const vc = new VirtualConsole();
|
||||
vc.on('jsdomError', e => errors.push(e.message));
|
||||
const dom = new JSDOM(buildPage(file), {
|
||||
runScripts: 'dangerously', pretendToBeVisual: true, virtualConsole: vc, url: 'http://localhost/',
|
||||
beforeParse(w) { w.scrollTo = function () {}; }
|
||||
});
|
||||
await wait(160);
|
||||
return { dom, errors, doc: dom.window.document };
|
||||
}
|
||||
|
||||
const CHAPTERS = [
|
||||
{ file: 'chemistry_7_ch1.html', cards: 15, first: 'sec-p1' },
|
||||
{ file: 'chemistry_7_ch2.html', cards: 8, first: 'sec-p13' },
|
||||
{ file: 'chemistry_7_ch3.html', cards: 9, first: 'sec-p18' },
|
||||
{ file: 'chemistry_7_ch4.html', cards: 7, first: 'sec-p23' }
|
||||
];
|
||||
|
||||
for (const ch of CHAPTERS) {
|
||||
test(`${ch.file}: SPA без ошибок, ${ch.cards} карточек, активен ${ch.first}`, async () => {
|
||||
const { doc, errors } = await loadDom(ch.file);
|
||||
assert.deepEqual(errors, [], 'нет ошибок: ' + errors.join(' | '));
|
||||
assert.equal(doc.querySelectorAll('#psel-grid .psel-card').length, ch.cards, ch.cards + ' карточек');
|
||||
const active = doc.querySelector('.sec.active');
|
||||
assert.ok(active && active.id === ch.first, 'активен ' + ch.first);
|
||||
const firstId = ch.first.replace('sec-', '');
|
||||
assert.ok(doc.querySelector('#' + firstId + '-body .para-hero'), 'para-hero первого §');
|
||||
assert.ok(doc.querySelector('#' + firstId + '-body .read-wrap'), 'кнопка прочтения первого §');
|
||||
});
|
||||
}
|
||||
|
||||
test('ch1: переход к §9 и финалу строит заглушку без ошибок', async () => {
|
||||
const { doc, errors } = await loadDom('chemistry_7_ch1.html');
|
||||
doc.defaultView.goTo('p9'); await wait(80);
|
||||
assert.ok(doc.querySelector('#p9-body .para-hero'), 'para-hero §9');
|
||||
doc.defaultView.goTo('final1'); await wait(80);
|
||||
assert.ok(doc.querySelector('#final1-body .para-hero'), 'para-hero финала');
|
||||
assert.equal(doc.querySelector('#final1-body .read-wrap'), null, 'у финала нет кнопки прочтения');
|
||||
assert.deepEqual(errors, [], 'нет ошибок: ' + errors.join(' | '));
|
||||
});
|
||||
|
||||
/* ── Хаб: каталог глав + финал курса ── */
|
||||
function buildHub() {
|
||||
let html = readF('frontend/textbooks/chemistry_7_hub.html');
|
||||
return html
|
||||
.replace(/<script defer src="https:\/\/cdn[^"]*"[^>]*><\/script>/g, '')
|
||||
.replace(/<script src="\/js\/api\.js" defer><\/script>/, '<script>window.renderMathInElement=function(){};</script>')
|
||||
.replace(/<script src="\/js\/xp\.js" defer><\/script>/, '');
|
||||
}
|
||||
async function loadHub() {
|
||||
const errors = []; const vc = new VirtualConsole(); vc.on('jsdomError', e => errors.push(e.message));
|
||||
const dom = new JSDOM(buildHub(), { runScripts: 'dangerously', pretendToBeVisual: true, virtualConsole: vc, url: 'http://localhost/', beforeParse(w){ w.scrollTo=function(){}; } });
|
||||
await wait(60);
|
||||
return { dom, errors, doc: dom.window.document };
|
||||
}
|
||||
|
||||
test('hub: 4 карточки глав, финал курса — 8 боссов, босс решается', async () => {
|
||||
const { doc, errors } = await loadHub();
|
||||
assert.deepEqual(errors, [], 'нет ошибок: ' + errors.join(' | '));
|
||||
assert.equal(doc.querySelectorAll('.ch-grid .ch-card').length, 4, '4 карточки глав');
|
||||
doc.getElementById('final-head').dispatchEvent(new doc.defaultView.Event('click', { bubbles: true }));
|
||||
await wait(40);
|
||||
assert.equal(doc.querySelectorAll('#fin-bosses-container .boss-card').length, 8, '8 боссов');
|
||||
// решить босс 1 (Mr H2SO4 = 98)
|
||||
const inp = doc.getElementById('fb-1-inp'), go = doc.getElementById('fb-1-go');
|
||||
inp.value = '98'; go.dispatchEvent(new doc.defaultView.Event('click', { bubbles: true }));
|
||||
assert.ok(doc.getElementById('fb-1-card').classList.contains('solved'), 'босс 1 повержен');
|
||||
});
|
||||
@@ -0,0 +1,53 @@
|
||||
/* chem7_svg.js — наглядные химические примитивы для учебника «Химия 7».
|
||||
*
|
||||
* Неймспейс: window.Chem7.*
|
||||
* Это ТОНКАЯ надстройка над window.Chem8 (chem8_svg.js): рендер формул и уравнений,
|
||||
* ионы переиспользуются из Chem8; здесь добавляется только то, что специфично для
|
||||
* первого курса химии 7 класса (валентность, разделение смесей, признаки реакций,
|
||||
* весы сохранения массы, горение, конструктор оксида/соли/основания, состав воздуха,
|
||||
* разложение воды, массовая доля элемента).
|
||||
*
|
||||
* Молекулярные модели (структурные / 2D / 3D) — НЕ здесь, а через biochem-core.js.
|
||||
*
|
||||
* Phase 0: переэкспортированы примитивы Chem8 (formula, ionLabel, chemEq, molarMass,
|
||||
* equationBalancer и т. п.); собственные звёздные виджеты — заглушки, наполняются в
|
||||
* фазах 1–4 (см. plans/textbooks-7/PLAN_CHEMISTRY_7.md, разд. B).
|
||||
*
|
||||
* Правила (CLAUDE.md / план):
|
||||
* - без эмоджи, только inline SVG .ic;
|
||||
* - в KaTeX-шаблонах двойной backslash (\\to, \\uparrow, \\downarrow);
|
||||
* - drag/слайдеры: window-listeners + state ВЫШЕ redraw(), без setPointerCapture.
|
||||
*/
|
||||
(function (global) {
|
||||
'use strict';
|
||||
|
||||
var C8 = global.Chem8 || {};
|
||||
function noop() { /* заглушка фазы 0 — реализуется в фазах 1–4 */ }
|
||||
|
||||
var Chem7 = {
|
||||
/* ── переиспользуем примитивы Chem8 (рендер формул/уравнений/ионов, M_r) ── */
|
||||
formula: C8.formula || function (s) { return s; },
|
||||
ionLabel: C8.ionLabel || function (s) { return s; },
|
||||
chemEq: C8.chemEq || function (s) { return s; },
|
||||
molarMass: C8.molarMass || function () { return NaN; },
|
||||
elementCounts: C8.elementCounts || function () { return null; },
|
||||
arOf: C8.arOf || function () { return ''; },
|
||||
fmt: C8.fmt || function (x) { return String(x).replace('.', ','); },
|
||||
equationBalancer: C8.equationBalancer || noop,
|
||||
|
||||
/* ── собственные звёздные виджеты Химии 7 (Phase 0: заглушки) ── */
|
||||
valenceBuilder: noop, // §9 — конструктор формулы по валентности (НОК индексов)
|
||||
elementSymbolDrill: noop, // §3 — тренажёр символ ↔ название
|
||||
atomBalance: noop, // §4 — «весы атомов», во сколько раз тяжелее
|
||||
mixtureSeparator: noop, // §2 — разделитель смесей (фильтр/выпаривание/магнит/дистилляция)
|
||||
reactionSigns: noop, // §10 — детектор признаков реакции
|
||||
massConservation: noop, // §11 — «весы сохранения массы»
|
||||
combustionSim: noop, // §15 — симулятор горения (вещество + O₂ → оксид)
|
||||
compoundBuilder: noop, // §16,22,24 — конструктор оксида/соли/основания
|
||||
airComposition: noop, // §13 — диаграмма состава воздуха
|
||||
waterDecomp: noop, // §23 — разложение воды (H₂:O₂ = 2:1)
|
||||
massFraction: noop // Прил.3/§8 — калькулятор массовой доли элемента
|
||||
};
|
||||
|
||||
global.Chem7 = Chem7;
|
||||
})(window);
|
||||
@@ -0,0 +1,132 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
||||
<meta http-equiv="Pragma" content="no-cache">
|
||||
<meta http-equiv="Expires" content="0">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>Химия 7 · Глава 1 · «Первоначальные химические понятия»</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800;900&family=Inter:wght@400;500;600;700&family=Unbounded:wght@700;800;900&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
|
||||
<link rel="stylesheet" href="/css/chem8-textbook.css">
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"></script>
|
||||
<script src="/js/api.js" defer></script>
|
||||
<script src="/js/xp.js" defer></script>
|
||||
<script src="/js/biochem-core.js" defer></script>
|
||||
<script src="/js/chem8_svg.js" defer></script>
|
||||
<script src="/js/chem7_svg.js" defer></script>
|
||||
<script src="/js/chem8_engine.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="hdr">
|
||||
<div class="hdr-row">
|
||||
<div>
|
||||
<h1>Химия 7 · Глава 1</h1>
|
||||
<div class="hdr-sub">Первоначальные химические понятия: вещество, атом, элемент, молекула, формула, валентность, реакция и уравнение</div>
|
||||
</div>
|
||||
<div class="hdr-side">
|
||||
<a href="/textbook/chemistry-7" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg> К главам</a>
|
||||
<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>
|
||||
|
||||
<main class="main">
|
||||
<div class="col-main">
|
||||
|
||||
<section class="hero">
|
||||
<h2>С чего начинается химия</h2>
|
||||
<p>Химия изучает вещества, их свойства и превращения. В этой главе вы научитесь главному «языку» химии: узнаете об атомах и химических элементах, научитесь записывать состав веществ формулами, определять валентность и составлять уравнения химических реакций.</p>
|
||||
<div class="hero-row">
|
||||
<button class="btn-primary" onclick="goTo('p1')"><svg class="ic" viewBox="0 0 24 24"><polygon points="6 4 20 12 6 20 6 4" fill="currentColor" stroke="none"/></svg> Начать § 1</button>
|
||||
<div class="hero-progress">
|
||||
<span class="hp-label">Прогресс главы</span>
|
||||
<div class="hp-bar"><div id="hero-hp-fill" class="hp-fill"></div></div>
|
||||
<span id="hero-hp-text" class="hp-text">0%</span>
|
||||
</div>
|
||||
<div id="hero-xp-badge" class="hero-xp-badge"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="psel">
|
||||
<div class="psel-title">Параграфы главы</div>
|
||||
<div id="psel-grid" class="psel-grid"></div>
|
||||
</section>
|
||||
|
||||
<section id="sec-p1" class="sec"><div class="sec-header"><span class="sec-num">§ 1</span><h2 class="sec-h">Химия — наука о веществах</h2></div><div id="p1-body"></div></section>
|
||||
<section id="sec-p2" class="sec"><div class="sec-header"><span class="sec-num">§ 2</span><h2 class="sec-h">Чистые вещества и смеси</h2></div><div id="p2-body"></div></section>
|
||||
<section id="sec-pr1" class="sec"><div class="sec-header"><span class="sec-num">ПР 1</span><h2 class="sec-h">Практическая работа: знакомство с лабораторией. Разделение смесей</h2></div><div id="pr1-body"></div></section>
|
||||
<section id="sec-p3" class="sec"><div class="sec-header"><span class="sec-num">§ 3</span><h2 class="sec-h">Атомы. Химические элементы</h2></div><div id="p3-body"></div></section>
|
||||
<section id="sec-p4" class="sec"><div class="sec-header"><span class="sec-num">§ 4</span><h2 class="sec-h">Относительная атомная масса химических элементов</h2></div><div id="p4-body"></div></section>
|
||||
<section id="sec-p5" class="sec"><div class="sec-header"><span class="sec-num">§ 5</span><h2 class="sec-h">Молекулы. Простые вещества</h2></div><div id="p5-body"></div></section>
|
||||
<section id="sec-p6" class="sec"><div class="sec-header"><span class="sec-num">§ 6</span><h2 class="sec-h">Сложные вещества</h2></div><div id="p6-body"></div></section>
|
||||
<section id="sec-p7" class="sec"><div class="sec-header"><span class="sec-num">§ 7</span><h2 class="sec-h">Химическая формула</h2></div><div id="p7-body"></div></section>
|
||||
<section id="sec-p8" class="sec"><div class="sec-header"><span class="sec-num">§ 8</span><h2 class="sec-h">Относительная молекулярная масса</h2></div><div id="p8-body"></div></section>
|
||||
<section id="sec-p9" class="sec"><div class="sec-header"><span class="sec-num">§ 9</span><h2 class="sec-h">Валентность</h2></div><div id="p9-body"></div></section>
|
||||
<section id="sec-p10" class="sec"><div class="sec-header"><span class="sec-num">§ 10</span><h2 class="sec-h">Явления физические и химические. Признаки химических реакций</h2></div><div id="p10-body"></div></section>
|
||||
<section id="sec-lo1" class="sec"><div class="sec-header"><span class="sec-num">Лаб. 1</span><h2 class="sec-h">Лабораторный опыт: признаки протекания химических реакций</h2></div><div id="lo1-body"></div></section>
|
||||
<section id="sec-p11" class="sec"><div class="sec-header"><span class="sec-num">§ 11</span><h2 class="sec-h">Закон сохранения массы веществ. Химические уравнения</h2></div><div id="p11-body"></div></section>
|
||||
<section id="sec-p12" class="sec"><div class="sec-header"><span class="sec-num">§ 12</span><h2 class="sec-h">Составление уравнений химических реакций</h2></div><div id="p12-body"></div></section>
|
||||
<section id="sec-final1" class="sec"><div class="sec-header"><span class="sec-num">★</span><h2 class="sec-h">Финал главы</h2></div><div id="final1-body"></div></section>
|
||||
|
||||
</div>
|
||||
<aside class="col-side"><div id="sidebar-content"></div></aside>
|
||||
</main>
|
||||
|
||||
<footer class="foot">Интерактивный учебник «Химия — 7 класс» · Глава 1 · «Первоначальные химические понятия» · LearnSpace</footer>
|
||||
<div id="ach-popup" class="ach-popup"><svg viewBox="0 0 24 24"><polygon points="12 2 22 20 2 20"/></svg><span id="ach-text">Достижение!</span></div>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
window.CHEM8_CFG = { slug:'chemistry-7-ch1', themeKey:'chemistry7_theme', xpKey:'chemistry7_xp',
|
||||
progKey:'chemistry7_ch1_progress', achKey:'chemistry7_ch1_ach', hubHref:'/textbook/chemistry-7' };
|
||||
|
||||
window.PARAS = [
|
||||
{id:'p1', num:'§ 1', name:'Химия — наука о веществах', sub:'вещество · свойства'},
|
||||
{id:'p2', num:'§ 2', name:'Чистые вещества и смеси', sub:'разделение смесей'},
|
||||
{id:'pr1', num:'ПР 1', name:'Практическая работа', sub:'разделение смесей'},
|
||||
{id:'p3', num:'§ 3', name:'Атомы. Химические элементы', sub:'символы элементов'},
|
||||
{id:'p4', num:'§ 4', name:'Относительная атомная масса', sub:'$A_r$'},
|
||||
{id:'p5', num:'§ 5', name:'Молекулы. Простые вещества', sub:'$O_2$, $H_2$'},
|
||||
{id:'p6', num:'§ 6', name:'Сложные вещества', sub:'$H_2O$, $CO_2$'},
|
||||
{id:'p7', num:'§ 7', name:'Химическая формула', sub:'индекс · состав'},
|
||||
{id:'p8', num:'§ 8', name:'Относительная молекулярная масса', sub:'$M_r=\\sum A_r$'},
|
||||
{id:'p9', num:'§ 9', name:'Валентность', sub:'H — I, O — II'},
|
||||
{id:'p10', num:'§ 10', name:'Физические и химические явления', sub:'признаки реакций'},
|
||||
{id:'lo1', num:'Лаб. 1', name:'Признаки реакций', sub:'опыт'},
|
||||
{id:'p11', num:'§ 11', name:'Закон сохранения массы', sub:'уравнения'},
|
||||
{id:'p12', num:'§ 12', name:'Составление уравнений', sub:'коэффициенты'},
|
||||
{id:'final1', num:'★', name:'Финал главы', sub:'босс · ачивка', final:true}
|
||||
];
|
||||
|
||||
window.ACH_LABELS = { start:'Начало главы 1!', final1_tasks:'Глава 1 пройдена!' };
|
||||
window.SIDEBARS = { p1:{ title:'Глава 1 · Химия 7', rows:[['Раздел','Первоначальные понятия'],['§§','1–12'],['Лаб/ПР','ЛО 1 · ПР 1']] } };
|
||||
window.TIPS = [{ sec:'p1', html:'Глава наполняется содержанием по фазам. Сейчас доступны навигация по параграфам и отметка о прочтении (+10 XP).' }];
|
||||
|
||||
/* Phase 0: заглушки-builder'ы из PARAS (теория и интерактивы добавляются в фазах 1–4). */
|
||||
(function(){
|
||||
var P = window.PARAS, B = {};
|
||||
function ph(p, prev, next){
|
||||
return function(){
|
||||
var el = document.getElementById(p.id + '-body'); if (!el) return;
|
||||
el.innerHTML =
|
||||
'<div class="para-hero"><div class="ph-label">' + p.num + ' · Химия 7</div><h2>' + p.name + '</h2>'
|
||||
+ '<div class="ph-desc">Содержание этого ' + (p.final ? 'раздела' : 'параграфа') + ' готовится.</div></div>'
|
||||
+ makeCard('theory', p.name, p.num,
|
||||
'<p>Скоро здесь появятся теория, наглядные SVG-схемы, молекулярные модели и интерактивные тренажёры по теме «' + p.name + '». Пока доступна навигация по главе' + (p.final ? '.' : ' и отметка о прочтении.') + '</p>')
|
||||
+ secNav(prev, next) + (p.final ? '' : readButton(p.id));
|
||||
if (!p.final) wireReadBtn(p.id);
|
||||
};
|
||||
}
|
||||
for (var i = 0; i < P.length; i++) {
|
||||
B[P[i].id] = ph(P[i], i > 0 ? P[i-1].id : null, i < P.length-1 ? P[i+1].id : null);
|
||||
}
|
||||
window.BUILDERS = B;
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,118 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
||||
<meta http-equiv="Pragma" content="no-cache">
|
||||
<meta http-equiv="Expires" content="0">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>Химия 7 · Глава 2 · «Кислород»</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800;900&family=Inter:wght@400;500;600;700&family=Unbounded:wght@700;800;900&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
|
||||
<link rel="stylesheet" href="/css/chem8-textbook.css">
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"></script>
|
||||
<script src="/js/api.js" defer></script>
|
||||
<script src="/js/xp.js" defer></script>
|
||||
<script src="/js/biochem-core.js" defer></script>
|
||||
<script src="/js/chem8_svg.js" defer></script>
|
||||
<script src="/js/chem7_svg.js" defer></script>
|
||||
<script src="/js/chem8_engine.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="hdr">
|
||||
<div class="hdr-row">
|
||||
<div>
|
||||
<h1>Химия 7 · Глава 2</h1>
|
||||
<div class="hdr-sub">Кислород: воздух, горение, оксиды, получение кислорода</div>
|
||||
</div>
|
||||
<div class="hdr-side">
|
||||
<a href="/textbook/chemistry-7" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg> К главам</a>
|
||||
<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>
|
||||
|
||||
<main class="main">
|
||||
<div class="col-main">
|
||||
|
||||
<section class="hero">
|
||||
<h2>Кислород — газ, который даёт жизнь и огонь</h2>
|
||||
<p>Кислород — самый распространённый элемент на Земле. Без него невозможны дыхание и горение. В этой главе вы узнаете состав воздуха, познакомитесь с кислородом как простым веществом, изучите горение и оксиды, научитесь получать кислород в лаборатории.</p>
|
||||
<div class="hero-row">
|
||||
<button class="btn-primary" onclick="goTo('p13')"><svg class="ic" viewBox="0 0 24 24"><polygon points="6 4 20 12 6 20 6 4" fill="currentColor" stroke="none"/></svg> Начать § 13</button>
|
||||
<div class="hero-progress">
|
||||
<span class="hp-label">Прогресс главы</span>
|
||||
<div class="hp-bar"><div id="hero-hp-fill" class="hp-fill"></div></div>
|
||||
<span id="hero-hp-text" class="hp-text">0%</span>
|
||||
</div>
|
||||
<div id="hero-xp-badge" class="hero-xp-badge"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="psel">
|
||||
<div class="psel-title">Параграфы главы</div>
|
||||
<div id="psel-grid" class="psel-grid"></div>
|
||||
</section>
|
||||
|
||||
<section id="sec-p13" class="sec"><div class="sec-header"><span class="sec-num">§ 13</span><h2 class="sec-h">Воздух как смесь газов</h2></div><div id="p13-body"></div></section>
|
||||
<section id="sec-lo2" class="sec"><div class="sec-header"><span class="sec-num">Лаб. 2</span><h2 class="sec-h">Лабораторный опыт: сборка приборов для получения и собирания газов</h2></div><div id="lo2-body"></div></section>
|
||||
<section id="sec-p14" class="sec"><div class="sec-header"><span class="sec-num">§ 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">§ 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">§ 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">§ 17</span><h2 class="sec-h">Получение кислорода</h2></div><div id="p17-body"></div></section>
|
||||
<section id="sec-pr2" class="sec"><div class="sec-header"><span class="sec-num">ПР 2</span><h2 class="sec-h">Практическая работа: получение кислорода и изучение его свойств</h2></div><div id="pr2-body"></div></section>
|
||||
<section id="sec-final2" class="sec"><div class="sec-header"><span class="sec-num">★</span><h2 class="sec-h">Финал главы</h2></div><div id="final2-body"></div></section>
|
||||
|
||||
</div>
|
||||
<aside class="col-side"><div id="sidebar-content"></div></aside>
|
||||
</main>
|
||||
|
||||
<footer class="foot">Интерактивный учебник «Химия — 7 класс» · Глава 2 · «Кислород» · LearnSpace</footer>
|
||||
<div id="ach-popup" class="ach-popup"><svg viewBox="0 0 24 24"><polygon points="12 2 22 20 2 20"/></svg><span id="ach-text">Достижение!</span></div>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
window.CHEM8_CFG = { slug:'chemistry-7-ch2', themeKey:'chemistry7_theme', xpKey:'chemistry7_xp',
|
||||
progKey:'chemistry7_ch2_progress', achKey:'chemistry7_ch2_ach', hubHref:'/textbook/chemistry-7' };
|
||||
|
||||
window.PARAS = [
|
||||
{id:'p13', num:'§ 13', name:'Воздух как смесь газов', sub:'$N_2$ · $O_2$'},
|
||||
{id:'lo2', num:'Лаб. 2', name:'Приборы для газов', sub:'опыт'},
|
||||
{id:'p14', num:'§ 14', name:'Кислород: элемент и вещество', sub:'$O$ · $O_2$ · $O_3$'},
|
||||
{id:'p15', num:'§ 15', name:'Химические свойства кислорода', sub:'горение'},
|
||||
{id:'p16', num:'§ 16', name:'Оксиды', sub:'Э + $O$'},
|
||||
{id:'p17', num:'§ 17', name:'Получение кислорода', sub:'разложение · катализатор'},
|
||||
{id:'pr2', num:'ПР 2', name:'Практическая работа', sub:'получение $O_2$'},
|
||||
{id:'final2', num:'★', name:'Финал главы', sub:'босс · ачивка', final:true}
|
||||
];
|
||||
|
||||
window.ACH_LABELS = { start:'Начало главы 2!', final2_tasks:'Глава 2 пройдена!' };
|
||||
window.SIDEBARS = { p13:{ title:'Глава 2 · Химия 7', rows:[['Раздел','Кислород'],['§§','13–17'],['Лаб/ПР','ЛО 2 · ПР 2']] } };
|
||||
window.TIPS = [{ sec:'p13', html:'Глава наполняется содержанием по фазам. Сейчас доступны навигация по параграфам и отметка о прочтении (+10 XP).' }];
|
||||
|
||||
/* Phase 0: заглушки-builder'ы из PARAS (теория и интерактивы добавляются в фазах 1–4). */
|
||||
(function(){
|
||||
var P = window.PARAS, B = {};
|
||||
function ph(p, prev, next){
|
||||
return function(){
|
||||
var el = document.getElementById(p.id + '-body'); if (!el) return;
|
||||
el.innerHTML =
|
||||
'<div class="para-hero"><div class="ph-label">' + p.num + ' · Химия 7</div><h2>' + p.name + '</h2>'
|
||||
+ '<div class="ph-desc">Содержание этого ' + (p.final ? 'раздела' : 'параграфа') + ' готовится.</div></div>'
|
||||
+ makeCard('theory', p.name, p.num,
|
||||
'<p>Скоро здесь появятся теория, наглядные SVG-схемы, молекулярные модели и интерактивные тренажёры по теме «' + p.name + '». Пока доступна навигация по главе' + (p.final ? '.' : ' и отметка о прочтении.') + '</p>')
|
||||
+ secNav(prev, next) + (p.final ? '' : readButton(p.id));
|
||||
if (!p.final) wireReadBtn(p.id);
|
||||
};
|
||||
}
|
||||
for (var i = 0; i < P.length; i++) {
|
||||
B[P[i].id] = ph(P[i], i > 0 ? P[i-1].id : null, i < P.length-1 ? P[i+1].id : null);
|
||||
}
|
||||
window.BUILDERS = B;
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,120 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
||||
<meta http-equiv="Pragma" content="no-cache">
|
||||
<meta http-equiv="Expires" content="0">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>Химия 7 · Глава 3 · «Водород»</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800;900&family=Inter:wght@400;500;600;700&family=Unbounded:wght@700;800;900&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
|
||||
<link rel="stylesheet" href="/css/chem8-textbook.css">
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"></script>
|
||||
<script src="/js/api.js" defer></script>
|
||||
<script src="/js/xp.js" defer></script>
|
||||
<script src="/js/biochem-core.js" defer></script>
|
||||
<script src="/js/chem8_svg.js" defer></script>
|
||||
<script src="/js/chem7_svg.js" defer></script>
|
||||
<script src="/js/chem8_engine.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="hdr">
|
||||
<div class="hdr-row">
|
||||
<div>
|
||||
<h1>Химия 7 · Глава 3</h1>
|
||||
<div class="hdr-sub">Водород: свойства, кислоты и индикаторы, ряд активности, соли</div>
|
||||
</div>
|
||||
<div class="hdr-side">
|
||||
<a href="/textbook/chemistry-7" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg> К главам</a>
|
||||
<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>
|
||||
|
||||
<main class="main">
|
||||
<div class="col-main">
|
||||
|
||||
<section class="hero">
|
||||
<h2>Водород — самый лёгкий элемент Вселенной</h2>
|
||||
<p>Водород — первый элемент периодической системы и самый распространённый во Вселенной. В этой главе вы изучите его свойства, познакомитесь с кислотами и индикаторами, узнаете, как металлы вытесняют водород из кислот, и что такое соли.</p>
|
||||
<div class="hero-row">
|
||||
<button class="btn-primary" onclick="goTo('p18')"><svg class="ic" viewBox="0 0 24 24"><polygon points="6 4 20 12 6 20 6 4" fill="currentColor" stroke="none"/></svg> Начать § 18</button>
|
||||
<div class="hero-progress">
|
||||
<span class="hp-label">Прогресс главы</span>
|
||||
<div class="hp-bar"><div id="hero-hp-fill" class="hp-fill"></div></div>
|
||||
<span id="hero-hp-text" class="hp-text">0%</span>
|
||||
</div>
|
||||
<div id="hero-xp-badge" class="hero-xp-badge"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="psel">
|
||||
<div class="psel-title">Параграфы главы</div>
|
||||
<div id="psel-grid" class="psel-grid"></div>
|
||||
</section>
|
||||
|
||||
<section id="sec-p18" class="sec"><div class="sec-header"><span class="sec-num">§ 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">§ 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">§ 20</span><h2 class="sec-h">Понятие о кислотах</h2></div><div id="p20-body"></div></section>
|
||||
<section id="sec-lo3" class="sec"><div class="sec-header"><span class="sec-num">Лаб. 3</span><h2 class="sec-h">Лабораторный опыт: действие кислот на индикаторы</h2></div><div id="lo3-body"></div></section>
|
||||
<section id="sec-p21" class="sec"><div class="sec-header"><span class="sec-num">§ 21</span><h2 class="sec-h">Взаимодействие кислот с металлами</h2></div><div id="p21-body"></div></section>
|
||||
<section id="sec-lo4" class="sec"><div class="sec-header"><span class="sec-num">Лаб. 4</span><h2 class="sec-h">Лабораторный опыт: взаимодействие серной и соляной кислот с металлами</h2></div><div id="lo4-body"></div></section>
|
||||
<section id="sec-p22" class="sec"><div class="sec-header"><span class="sec-num">§ 22</span><h2 class="sec-h">Соли — продукты замещения атомов водорода в кислотах на металлы</h2></div><div id="p22-body"></div></section>
|
||||
<section id="sec-pr3" class="sec"><div class="sec-header"><span class="sec-num">ПР 3</span><h2 class="sec-h">Практическая работа: получение водорода и изучение его свойств</h2></div><div id="pr3-body"></div></section>
|
||||
<section id="sec-final3" class="sec"><div class="sec-header"><span class="sec-num">★</span><h2 class="sec-h">Финал главы</h2></div><div id="final3-body"></div></section>
|
||||
|
||||
</div>
|
||||
<aside class="col-side"><div id="sidebar-content"></div></aside>
|
||||
</main>
|
||||
|
||||
<footer class="foot">Интерактивный учебник «Химия — 7 класс» · Глава 3 · «Водород» · LearnSpace</footer>
|
||||
<div id="ach-popup" class="ach-popup"><svg viewBox="0 0 24 24"><polygon points="12 2 22 20 2 20"/></svg><span id="ach-text">Достижение!</span></div>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
window.CHEM8_CFG = { slug:'chemistry-7-ch3', themeKey:'chemistry7_theme', xpKey:'chemistry7_xp',
|
||||
progKey:'chemistry7_ch3_progress', achKey:'chemistry7_ch3_ach', hubHref:'/textbook/chemistry-7' };
|
||||
|
||||
window.PARAS = [
|
||||
{id:'p18', num:'§ 18', name:'Водород: элемент и вещество', sub:'$H$ · $H_2$'},
|
||||
{id:'p19', num:'§ 19', name:'Химические свойства водорода', sub:'восстановление'},
|
||||
{id:'p20', num:'§ 20', name:'Понятие о кислотах', sub:'индикаторы'},
|
||||
{id:'lo3', num:'Лаб. 3', name:'Кислоты и индикаторы', sub:'опыт'},
|
||||
{id:'p21', num:'§ 21', name:'Кислоты и металлы', sub:'ряд активности'},
|
||||
{id:'lo4', num:'Лаб. 4', name:'Кислоты с металлами', sub:'опыт'},
|
||||
{id:'p22', num:'§ 22', name:'Соли', sub:'замещение'},
|
||||
{id:'pr3', num:'ПР 3', name:'Практическая работа', sub:'получение $H_2$'},
|
||||
{id:'final3', num:'★', name:'Финал главы', sub:'босс · ачивка', final:true}
|
||||
];
|
||||
|
||||
window.ACH_LABELS = { start:'Начало главы 3!', final3_tasks:'Глава 3 пройдена!' };
|
||||
window.SIDEBARS = { p18:{ title:'Глава 3 · Химия 7', rows:[['Раздел','Водород'],['§§','18–22'],['Лаб/ПР','ЛО 3,4 · ПР 3']] } };
|
||||
window.TIPS = [{ sec:'p18', html:'Глава наполняется содержанием по фазам. Сейчас доступны навигация по параграфам и отметка о прочтении (+10 XP).' }];
|
||||
|
||||
/* Phase 0: заглушки-builder'ы из PARAS (теория и интерактивы добавляются в фазах 1–4). */
|
||||
(function(){
|
||||
var P = window.PARAS, B = {};
|
||||
function ph(p, prev, next){
|
||||
return function(){
|
||||
var el = document.getElementById(p.id + '-body'); if (!el) return;
|
||||
el.innerHTML =
|
||||
'<div class="para-hero"><div class="ph-label">' + p.num + ' · Химия 7</div><h2>' + p.name + '</h2>'
|
||||
+ '<div class="ph-desc">Содержание этого ' + (p.final ? 'раздела' : 'параграфа') + ' готовится.</div></div>'
|
||||
+ makeCard('theory', p.name, p.num,
|
||||
'<p>Скоро здесь появятся теория, наглядные SVG-схемы, молекулярные модели и интерактивные тренажёры по теме «' + p.name + '». Пока доступна навигация по главе' + (p.final ? '.' : ' и отметка о прочтении.') + '</p>')
|
||||
+ secNav(prev, next) + (p.final ? '' : readButton(p.id));
|
||||
if (!p.final) wireReadBtn(p.id);
|
||||
};
|
||||
}
|
||||
for (var i = 0; i < P.length; i++) {
|
||||
B[P[i].id] = ph(P[i], i > 0 ? P[i-1].id : null, i < P.length-1 ? P[i+1].id : null);
|
||||
}
|
||||
window.BUILDERS = B;
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,116 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
||||
<meta http-equiv="Pragma" content="no-cache">
|
||||
<meta http-equiv="Expires" content="0">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>Химия 7 · Глава 4 · «Вода»</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800;900&family=Inter:wght@400;500;600;700&family=Unbounded:wght@700;800;900&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
|
||||
<link rel="stylesheet" href="/css/chem8-textbook.css">
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"></script>
|
||||
<script src="/js/api.js" defer></script>
|
||||
<script src="/js/xp.js" defer></script>
|
||||
<script src="/js/biochem-core.js" defer></script>
|
||||
<script src="/js/chem8_svg.js" defer></script>
|
||||
<script src="/js/chem7_svg.js" defer></script>
|
||||
<script src="/js/chem8_engine.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="hdr">
|
||||
<div class="hdr-row">
|
||||
<div>
|
||||
<h1>Химия 7 · Глава 4</h1>
|
||||
<div class="hdr-sub">Вода: состав и свойства, основания и индикаторы, нейтрализация, охрана природы</div>
|
||||
</div>
|
||||
<div class="hdr-side">
|
||||
<a href="/textbook/chemistry-7" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg> К главам</a>
|
||||
<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>
|
||||
|
||||
<main class="main">
|
||||
<div class="col-main">
|
||||
|
||||
<section class="hero">
|
||||
<h2>Вода — самое важное вещество на Земле</h2>
|
||||
<p>Вода знакома каждому, но в химии она удивительна. В этой главе вы изучите состав и свойства воды, познакомитесь с основаниями и индикаторами, узнаете о реакции нейтрализации и о том, как беречь воду и окружающую среду.</p>
|
||||
<div class="hero-row">
|
||||
<button class="btn-primary" onclick="goTo('p23')"><svg class="ic" viewBox="0 0 24 24"><polygon points="6 4 20 12 6 20 6 4" fill="currentColor" stroke="none"/></svg> Начать § 23</button>
|
||||
<div class="hero-progress">
|
||||
<span class="hp-label">Прогресс главы</span>
|
||||
<div class="hp-bar"><div id="hero-hp-fill" class="hp-fill"></div></div>
|
||||
<span id="hero-hp-text" class="hp-text">0%</span>
|
||||
</div>
|
||||
<div id="hero-xp-badge" class="hero-xp-badge"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="psel">
|
||||
<div class="psel-title">Параграфы главы</div>
|
||||
<div id="psel-grid" class="psel-grid"></div>
|
||||
</section>
|
||||
|
||||
<section id="sec-p23" class="sec"><div class="sec-header"><span class="sec-num">§ 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">§ 24</span><h2 class="sec-h">Основания как сложные вещества</h2></div><div id="p24-body"></div></section>
|
||||
<section id="sec-lo5" class="sec"><div class="sec-header"><span class="sec-num">Лаб. 5</span><h2 class="sec-h">Лабораторный опыт: действие щелочей на индикаторы</h2></div><div id="lo5-body"></div></section>
|
||||
<section id="sec-p25" class="sec"><div class="sec-header"><span class="sec-num">§ 25</span><h2 class="sec-h">Реакция нейтрализации</h2></div><div id="p25-body"></div></section>
|
||||
<section id="sec-pr4" class="sec"><div class="sec-header"><span class="sec-num">ПР 4</span><h2 class="sec-h">Практическая работа: реакция нейтрализации</h2></div><div id="pr4-body"></div></section>
|
||||
<section id="sec-p26" class="sec"><div class="sec-header"><span class="sec-num">§ 26</span><h2 class="sec-h">Охрана окружающей среды</h2></div><div id="p26-body"></div></section>
|
||||
<section id="sec-final4" class="sec"><div class="sec-header"><span class="sec-num">★</span><h2 class="sec-h">Финал главы</h2></div><div id="final4-body"></div></section>
|
||||
|
||||
</div>
|
||||
<aside class="col-side"><div id="sidebar-content"></div></aside>
|
||||
</main>
|
||||
|
||||
<footer class="foot">Интерактивный учебник «Химия — 7 класс» · Глава 4 · «Вода» · LearnSpace</footer>
|
||||
<div id="ach-popup" class="ach-popup"><svg viewBox="0 0 24 24"><polygon points="12 2 22 20 2 20"/></svg><span id="ach-text">Достижение!</span></div>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
window.CHEM8_CFG = { slug:'chemistry-7-ch4', themeKey:'chemistry7_theme', xpKey:'chemistry7_xp',
|
||||
progKey:'chemistry7_ch4_progress', achKey:'chemistry7_ch4_ach', hubHref:'/textbook/chemistry-7' };
|
||||
|
||||
window.PARAS = [
|
||||
{id:'p23', num:'§ 23', name:'Состав и свойства воды', sub:'$H_2O$'},
|
||||
{id:'p24', num:'§ 24', name:'Основания', sub:'Me + OH'},
|
||||
{id:'lo5', num:'Лаб. 5', name:'Щёлочи и индикаторы', sub:'опыт'},
|
||||
{id:'p25', num:'§ 25', name:'Реакция нейтрализации', sub:'кислота + основание'},
|
||||
{id:'pr4', num:'ПР 4', name:'Практическая работа', sub:'нейтрализация'},
|
||||
{id:'p26', num:'§ 26', name:'Охрана окружающей среды', sub:'вода · экология'},
|
||||
{id:'final4', num:'★', name:'Финал главы', sub:'босс · ачивка', final:true}
|
||||
];
|
||||
|
||||
window.ACH_LABELS = { start:'Начало главы 4!', final4_tasks:'Глава 4 пройдена!' };
|
||||
window.SIDEBARS = { p23:{ title:'Глава 4 · Химия 7', rows:[['Раздел','Вода'],['§§','23–26'],['Лаб/ПР','ЛО 5 · ПР 4']] } };
|
||||
window.TIPS = [{ sec:'p23', html:'Глава наполняется содержанием по фазам. Сейчас доступны навигация по параграфам и отметка о прочтении (+10 XP).' }];
|
||||
|
||||
/* Phase 0: заглушки-builder'ы из PARAS (теория и интерактивы добавляются в фазах 1–4). */
|
||||
(function(){
|
||||
var P = window.PARAS, B = {};
|
||||
function ph(p, prev, next){
|
||||
return function(){
|
||||
var el = document.getElementById(p.id + '-body'); if (!el) return;
|
||||
el.innerHTML =
|
||||
'<div class="para-hero"><div class="ph-label">' + p.num + ' · Химия 7</div><h2>' + p.name + '</h2>'
|
||||
+ '<div class="ph-desc">Содержание этого ' + (p.final ? 'раздела' : 'параграфа') + ' готовится.</div></div>'
|
||||
+ makeCard('theory', p.name, p.num,
|
||||
'<p>Скоро здесь появятся теория, наглядные SVG-схемы, молекулярные модели и интерактивные тренажёры по теме «' + p.name + '». Пока доступна навигация по главе' + (p.final ? '.' : ' и отметка о прочтении.') + '</p>')
|
||||
+ secNav(prev, next) + (p.final ? '' : readButton(p.id));
|
||||
if (!p.final) wireReadBtn(p.id);
|
||||
};
|
||||
}
|
||||
for (var i = 0; i < P.length; i++) {
|
||||
B[P[i].id] = ph(P[i], i > 0 ? P[i-1].id : null, i < P.length-1 ? P[i+1].id : null);
|
||||
}
|
||||
window.BUILDERS = B;
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,540 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
||||
<meta http-equiv="Pragma" content="no-cache">
|
||||
<meta http-equiv="Expires" content="0">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>Химия 7 класс — учебник</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800;900&family=Inter:wght@400;500;600;700&family=Unbounded:wght@400;700;800;900&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"></script>
|
||||
<script src="/js/api.js" defer></script>
|
||||
<script src="/js/xp.js" defer></script>
|
||||
<style>
|
||||
:root{
|
||||
--bg:#f0fdf4; --card:#fff;
|
||||
--text:#0f291c; --muted:#5b7a68;
|
||||
--border:#bbf7d0;
|
||||
--pri:#059669; --pri-d:#047857;
|
||||
--pri-soft:#d1fae5;
|
||||
--c1:#059669; --c1-d:#047857; /* гл.1 — emerald */
|
||||
--c2:#0891b2; --c2-d:#0e7490; /* гл.2 — cyan */
|
||||
--c3:#7c3aed; --c3-d:#6d28d9; /* гл.3 — violet */
|
||||
--c4:#2563eb; --c4-d:#1d4ed8; /* гл.4 — blue */
|
||||
--sh:0 4px 16px rgba(5,150,105,.10);
|
||||
--sh-h:0 12px 36px rgba(5,150,105,.18);
|
||||
}
|
||||
html.dark{
|
||||
--bg:#0a1a12; --card:#10241a;
|
||||
--text:#d1fae5; --muted:#8fb8a2;
|
||||
--border:#1f4030;
|
||||
--pri-soft:rgba(5,150,105,.16);
|
||||
}
|
||||
*{margin:0;padding:0;box-sizing:border-box}
|
||||
html,body{min-height:100vh}
|
||||
body{font-family:'Inter',system-ui,sans-serif;background:var(--bg);color:var(--text);line-height:1.55;transition:background .25s,color .25s}
|
||||
|
||||
/* HEADER */
|
||||
.hdr{position:relative;background:linear-gradient(110deg,#065f46 0%,#059669 55%,#6ee7b7 100%);color:#fff;padding:32px 24px 28px;overflow:hidden;border-bottom:2px solid rgba(209,250,229,.18)}
|
||||
.hdr::before{content:'ХИМИЯ';position:absolute;right:-14px;top:-18%;font-family:'Outfit',sans-serif;font-size:clamp(5rem,16vw,13rem);font-weight:900;letter-spacing:-.04em;color:transparent;-webkit-text-stroke:1.5px rgba(209,250,229,.16);line-height:1;pointer-events:none;user-select:none}
|
||||
.hdr-inner{position:relative;z-index:1;max-width:1100px;margin:0 auto;display:flex;align-items:center;gap:18px;flex-wrap:wrap}
|
||||
.hdr-back{display:inline-flex;align-items:center;gap:8px;padding:8px 14px;background:rgba(255,255,255,.16);border-radius:9px;color:#fff;text-decoration:none;font-size:.85rem;font-weight:600;transition:background .15s}
|
||||
.hdr-back:hover{background:rgba(255,255,255,.26)}
|
||||
.hdr h1{font-family:'Outfit',sans-serif;font-size:1.85rem;font-weight:900;letter-spacing:-.01em}
|
||||
.hdr-sub{font-size:.92rem;opacity:.9;margin-top:4px}
|
||||
.hdr-side{margin-left:auto;display:flex;gap:8px}
|
||||
.hdr-btn{padding:8px 12px;background:rgba(255,255,255,.16);border:none;color:#fff;border-radius:9px;cursor:pointer;font-weight:600;font-size:.82rem;display:inline-flex;align-items:center;gap:6px;transition:background .15s;font-family:inherit}
|
||||
.hdr-btn:hover{background:rgba(255,255,255,.26)}
|
||||
.ic{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
|
||||
|
||||
main{max-width:1100px;margin:0 auto;padding:32px 24px 60px}
|
||||
|
||||
/* OVERALL PROGRESS */
|
||||
.prog-overall{background:linear-gradient(135deg,var(--pri-soft),rgba(110,231,183,.12));border:1px solid var(--border);border-radius:14px;padding:14px 18px;margin-bottom:28px;display:flex;gap:14px;align-items:center;flex-wrap:wrap}
|
||||
.po-icon{width:46px;height:46px;border-radius:12px;background:linear-gradient(135deg,#059669,#6ee7b7);color:#fff;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-family:'Outfit',sans-serif;font-size:1.4rem;font-weight:900}
|
||||
.po-text{flex:1;min-width:160px}
|
||||
.po-label{font-size:.78rem;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.06em;margin-bottom:4px}
|
||||
.po-bar{height:8px;background:rgba(5,150,105,.16);border-radius:5px;overflow:hidden;margin-top:6px}
|
||||
.po-fill{height:100%;background:linear-gradient(90deg,var(--pri),#6ee7b7);border-radius:5px;transition:width .5s}
|
||||
.po-xp{display:inline-flex;align-items:center;gap:6px;padding:6px 14px;background:linear-gradient(135deg,#10b981,var(--pri));color:#fff;border-radius:99px;font-size:.8rem;font-weight:800;font-family:'Unbounded',sans-serif;letter-spacing:.02em;box-shadow:0 4px 12px rgba(5,150,105,.24)}
|
||||
|
||||
/* CHAPTER GRID */
|
||||
.ch-grid{display:grid;grid-template-columns:1fr;gap:18px;margin-bottom:30px}
|
||||
@media(min-width:680px){.ch-grid{grid-template-columns:1fr 1fr}}
|
||||
|
||||
.ch-card{background:var(--card);border:1.5px solid var(--border);border-radius:18px;overflow:hidden;display:flex;flex-direction:column;transition:transform .2s,box-shadow .2s,border-color .2s;cursor:pointer;text-decoration:none;color:inherit}
|
||||
.ch-card:hover{transform:translateY(-4px);box-shadow:var(--sh-h)}
|
||||
.ch-cover{padding:22px 22px 18px;color:#fff;position:relative;overflow:hidden}
|
||||
.ch-cover-wm{position:absolute;right:-4px;top:-14px;font-size:4rem;font-weight:900;font-family:'Outfit',sans-serif;line-height:1;color:rgba(255,255,255,.22);pointer-events:none;letter-spacing:-.03em}
|
||||
.ch-num{display:inline-block;padding:4px 10px;background:rgba(255,255,255,.24);border-radius:99px;font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:8px;position:relative;z-index:1}
|
||||
.ch-title{font-family:'Outfit',sans-serif;font-size:1.1rem;font-weight:800;letter-spacing:-.01em;position:relative;z-index:1;line-height:1.3}
|
||||
.ch-range{font-size:.84rem;opacity:.9;margin-top:4px;position:relative;z-index:1;font-weight:500}
|
||||
|
||||
.ch-cover.cc1{background:linear-gradient(135deg,#064e3b,#059669 60%,#34d399)}
|
||||
.ch-cover.cc2{background:linear-gradient(135deg,#164e63,#0891b2 60%,#22d3ee)}
|
||||
.ch-cover.cc3{background:linear-gradient(135deg,#4c1d95,#7c3aed 60%,#a78bfa)}
|
||||
.ch-cover.cc4{background:linear-gradient(135deg,#1e3a8a,#2563eb 60%,#60a5fa)}
|
||||
|
||||
.ch-body{padding:16px 20px 18px;display:flex;flex-direction:column;flex:1}
|
||||
.ch-desc{font-size:.88rem;color:var(--text);opacity:.84;flex:1;margin-bottom:12px;line-height:1.55}
|
||||
|
||||
.ch-prog{margin-bottom:12px}
|
||||
.ch-prog-label{display:flex;justify-content:space-between;font-size:.74rem;color:var(--muted);font-weight:600;margin-bottom:4px}
|
||||
.ch-prog-bar{height:6px;background:rgba(0,0,0,.07);border-radius:4px;overflow:hidden}
|
||||
.ch-prog-fill{height:100%;border-radius:4px;transition:width .5s}
|
||||
.ch-card.k1 .ch-prog-fill{background:linear-gradient(90deg,var(--c1),var(--c1-d))}
|
||||
.ch-card.k2 .ch-prog-fill{background:linear-gradient(90deg,var(--c2),var(--c2-d))}
|
||||
.ch-card.k3 .ch-prog-fill{background:linear-gradient(90deg,var(--c3),var(--c3-d))}
|
||||
.ch-card.k4 .ch-prog-fill{background:linear-gradient(90deg,var(--c4),var(--c4-d))}
|
||||
|
||||
.ch-action{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-radius:11px;font-weight:700;font-size:.9rem;color:#fff;transition:filter .15s}
|
||||
.ch-action:hover{filter:brightness(1.08)}
|
||||
.ch-card.k1 .ch-action{background:linear-gradient(135deg,var(--c1),#34d399)}
|
||||
.ch-card.k2 .ch-action{background:linear-gradient(135deg,var(--c2),#22d3ee)}
|
||||
.ch-card.k3 .ch-action{background:linear-gradient(135deg,var(--c3),#a78bfa)}
|
||||
.ch-card.k4 .ch-action{background:linear-gradient(135deg,var(--c4),#60a5fa)}
|
||||
|
||||
/* COURSE FINAL */
|
||||
.final-wrap{margin:0 0 28px;background:var(--card);border:1.5px solid var(--border);border-radius:18px;overflow:hidden;box-shadow:var(--sh)}
|
||||
.final-head{padding:18px 22px;background:linear-gradient(135deg,#065f46 0%,#059669 55%,#34d399 100%);color:#fff;cursor:pointer;display:flex;align-items:center;gap:14px;user-select:none;transition:filter .15s}
|
||||
.final-head:hover{filter:brightness(1.06)}
|
||||
.final-head-icon{width:46px;height:46px;border-radius:12px;background:rgba(255,255,255,.2);display:flex;align-items:center;justify-content:center;flex-shrink:0}
|
||||
.final-head-icon svg{width:26px;height:26px;stroke:#fff;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
|
||||
.final-head-text{flex:1;min-width:0}
|
||||
.final-head-tag{display:inline-block;padding:3px 9px;background:rgba(255,255,255,.24);border-radius:99px;font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:4px}
|
||||
.final-head-title{font-family:'Outfit',sans-serif;font-size:1.18rem;font-weight:800;letter-spacing:-.01em;line-height:1.25}
|
||||
.final-head-sub{font-size:.84rem;opacity:.9;margin-top:2px}
|
||||
.final-chevron{flex-shrink:0;transition:transform .25s}
|
||||
.final-chevron svg{width:24px;height:24px;stroke:#fff;fill:none;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
|
||||
.final-wrap.open .final-chevron{transform:rotate(180deg)}
|
||||
.final-body{display:none;padding:22px}
|
||||
.final-wrap.open .final-body{display:block}
|
||||
.fin-section-title{font-family:'Outfit',sans-serif;font-size:1.12rem;font-weight:800;color:var(--text);margin:8px 0 14px;display:flex;align-items:center;gap:9px}
|
||||
.fin-section-title svg{width:20px;height:20px;stroke:var(--pri);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
|
||||
.cheat-grid{display:grid;grid-template-columns:1fr;gap:14px;margin-bottom:28px}
|
||||
@media(min-width:680px){.cheat-grid{grid-template-columns:1fr 1fr}}
|
||||
.cheat-card{border:1.5px solid var(--border);border-radius:13px;padding:14px 16px;background:var(--card);position:relative;overflow:hidden}
|
||||
.cheat-card::before{content:'';position:absolute;left:0;top:0;bottom:0;width:4px}
|
||||
.cheat-card.c1::before{background:#059669}.cheat-card.c2::before{background:#0891b2}.cheat-card.c3::before{background:#7c3aed}.cheat-card.c4::before{background:#2563eb}
|
||||
.cheat-head{display:flex;align-items:center;gap:9px;margin-bottom:9px;padding-left:6px}
|
||||
.cheat-badge{font-size:.68rem;font-weight:800;padding:2px 8px;border-radius:99px;color:#fff;letter-spacing:.04em;text-transform:uppercase}
|
||||
.cheat-card.c1 .cheat-badge{background:#059669}.cheat-card.c2 .cheat-badge{background:#0891b2}.cheat-card.c3 .cheat-badge{background:#7c3aed}.cheat-card.c4 .cheat-badge{background:#2563eb}
|
||||
.cheat-title{font-weight:800;color:var(--text);font-size:.96rem}
|
||||
.cheat-list{list-style:none;padding-left:6px;margin:0}
|
||||
.cheat-list li{padding:6px 0;border-bottom:1px dashed var(--border);font-size:.9rem;line-height:1.5;color:var(--text)}
|
||||
.cheat-list li:last-child{border-bottom:0}
|
||||
.boss-overall-bar{background:linear-gradient(135deg,var(--pri-soft),rgba(110,231,183,.08));border:1px solid var(--border);border-radius:12px;padding:13px 16px;margin:6px 0 18px;display:flex;gap:14px;align-items:center;flex-wrap:wrap}
|
||||
.boss-overall-bar .lab{font-weight:700;font-size:.95rem;color:var(--text);min-width:200px}
|
||||
.boss-overall-bar .bar{flex:1;min-width:160px;height:9px;background:rgba(5,150,105,.16);border-radius:5px;overflow:hidden}
|
||||
.boss-overall-bar .fill{height:100%;background:linear-gradient(90deg,var(--pri),#6ee7b7);transition:width .5s;border-radius:5px}
|
||||
.boss-card{background:var(--card);border:2px solid var(--border);border-radius:14px;padding:16px;margin-bottom:14px;transition:border-color .35s,box-shadow .35s}
|
||||
.boss-card.solved{border-color:#10b981;box-shadow:0 0 0 3px rgba(16,185,129,.18)}
|
||||
.boss-head{display:flex;align-items:center;gap:10px;margin-bottom:10px;flex-wrap:wrap}
|
||||
.boss-tag{font-size:.68rem;font-weight:800;padding:3px 9px;border-radius:99px;background:var(--pri-soft);color:var(--pri-d);letter-spacing:.04em;text-transform:uppercase}
|
||||
.boss-title{font-family:'Outfit',sans-serif;font-weight:800;color:var(--text);font-size:1rem;flex:1;min-width:0}
|
||||
.boss-q{padding:12px 14px;background:var(--pri-soft);border-radius:10px;font-size:.95rem;line-height:1.55;margin-bottom:10px;color:var(--text)}
|
||||
.boss-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:6px}
|
||||
.boss-input{padding:8px 12px;border:1.5px solid var(--border);border-radius:8px;background:var(--card);color:var(--text);font-family:'JetBrains Mono',monospace;width:130px;text-align:center;font-size:.95rem}
|
||||
.boss-input:focus{outline:0;border-color:var(--pri);box-shadow:0 0 0 3px var(--pri-soft)}
|
||||
.boss-btn{padding:8px 16px;border-radius:9px;background:var(--card);color:var(--text);border:1.5px solid var(--border);font-weight:700;font-size:.88rem;cursor:pointer;font-family:inherit;transition:.15s}
|
||||
.boss-btn:hover{background:var(--pri-soft);border-color:var(--pri)}
|
||||
.boss-btn.primary{background:linear-gradient(135deg,var(--pri),#34d399);color:#fff;border-color:transparent}
|
||||
.boss-fb{padding:10px 14px;border-radius:9px;font-weight:600;font-size:.88rem;margin-top:8px;display:none;line-height:1.45}
|
||||
.boss-fb.ok{display:block;background:#d1fae5;color:#065f46;border-left:4px solid #10b981}
|
||||
.boss-fb.fail{display:block;background:#fee2e2;color:#7f1d1d;border-left:4px solid #dc2626}
|
||||
html.dark .boss-fb.ok{background:rgba(16,185,129,.18);color:#a7f3d0}html.dark .boss-fb.fail{background:rgba(220,38,38,.18);color:#fecaca}
|
||||
.boss-hint-txt{margin-top:8px;padding:9px 13px;background:rgba(16,185,129,.12);border-left:3px solid #10b981;border-radius:6px;font-size:.86rem;color:var(--text);display:none;line-height:1.5}
|
||||
.boss-hint-txt.show{display:block}
|
||||
.final-cta{margin-top:24px;padding:18px 20px;border-radius:14px;background:linear-gradient(135deg,#d1fae5,#a7f3d0);border:1.5px solid #34d399;display:none;align-items:center;gap:14px;flex-wrap:wrap}
|
||||
.final-cta.show{display:flex}
|
||||
html.dark .final-cta{background:linear-gradient(135deg,rgba(16,185,129,.18),rgba(5,150,105,.15));border-color:#059669}
|
||||
.final-cta-icon{width:48px;height:48px;border-radius:12px;background:linear-gradient(135deg,#34d399,#10b981);display:flex;align-items:center;justify-content:center;flex-shrink:0}
|
||||
.final-cta-icon svg{width:28px;height:28px;stroke:#fff;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
|
||||
.final-cta-txt{flex:1;min-width:180px}
|
||||
.final-cta-title{font-weight:800;color:#065f46;font-size:1.05rem;font-family:'Outfit',sans-serif}
|
||||
html.dark .final-cta-title{color:#a7f3d0}
|
||||
.final-cta-sub{font-size:.86rem;color:#047857;margin-top:2px}html.dark .final-cta-sub{color:#6ee7b7}
|
||||
.final-cta-btn{padding:10px 18px;border-radius:10px;background:linear-gradient(135deg,var(--pri),#10b981);color:#fff;text-decoration:none;font-weight:800;font-size:.9rem;display:inline-flex;align-items:center;gap:7px;transition:filter .15s}
|
||||
.final-cta-btn:hover{filter:brightness(1.1)}
|
||||
.final-cta-btn svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
|
||||
|
||||
/* ACHIEVEMENT STRIP */
|
||||
.ach-strip{background:var(--card);border:1.5px solid var(--border);border-radius:16px;padding:18px 22px;margin-bottom:28px;display:flex;align-items:center;gap:16px;transition:border-color .4s,box-shadow .4s}
|
||||
.ach-strip.lit{border-color:#10b981;box-shadow:0 0 0 3px rgba(16,185,129,.18)}
|
||||
.ach-icon{width:52px;height:52px;border-radius:14px;background:rgba(0,0,0,.06);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background .4s}
|
||||
.ach-strip.lit .ach-icon{background:linear-gradient(135deg,#34d399,#10b981)}
|
||||
.ach-icon svg{width:28px;height:28px;stroke:var(--muted);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
|
||||
.ach-strip.lit .ach-icon svg{stroke:#fff}
|
||||
.ach-text{flex:1}
|
||||
.ach-title{font-weight:800;font-size:1.02rem;color:var(--text)}
|
||||
.ach-sub{font-size:.85rem;color:var(--muted);margin-top:2px}
|
||||
.ach-strip.lit .ach-title{color:#065f46}
|
||||
html.dark .ach-strip.lit .ach-title{color:#a7f3d0}
|
||||
|
||||
.foot{text-align:center;padding:24px 16px;color:var(--muted);font-size:.78rem;border-top:1px solid var(--border)}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="hdr">
|
||||
<div class="hdr-inner">
|
||||
<div>
|
||||
<a href="/textbooks" class="hdr-back">
|
||||
<svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
|
||||
К каталогу
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<h1>Химия — 7 класс</h1>
|
||||
<div class="hdr-sub">Первый курс химии: вещества и реакции, кислород, водород, вода. 4 главы, 26 параграфов, 5 лабораторных опытов, 4 практические работы.</div>
|
||||
</div>
|
||||
<div class="hdr-side">
|
||||
<button id="theme-btn" class="hdr-btn" title="Сменить тему">
|
||||
<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>
|
||||
|
||||
<main>
|
||||
|
||||
<section class="prog-overall">
|
||||
<div class="po-icon">Х</div>
|
||||
<div class="po-text">
|
||||
<div class="po-label">Общий прогресс по курсу</div>
|
||||
<div id="overall-text" style="font-size:1.05rem;font-weight:700">Загрузка...</div>
|
||||
<div class="po-bar"><div id="overall-fill" class="po-fill" style="width:0%"></div></div>
|
||||
</div>
|
||||
<div id="hero-xp-badge" class="po-xp" style="display:none" data-gamified>0 XP</div>
|
||||
</section>
|
||||
|
||||
<div class="ch-grid">
|
||||
|
||||
<a href="/textbook/chemistry-7-ch1" class="ch-card k1" id="ch-1">
|
||||
<div class="ch-cover cc1">
|
||||
<div class="ch-cover-wm">Aₕ</div>
|
||||
<div class="ch-num">Глава 1</div>
|
||||
<div class="ch-title">Первоначальные химические понятия</div>
|
||||
<div class="ch-range">§1–§12 · ЛО 1 · ПР 1</div>
|
||||
</div>
|
||||
<div class="ch-body">
|
||||
<div class="ch-desc">Вещества и смеси, атомы и химические элементы, относительная атомная масса, молекулы, простые и сложные вещества, химическая формула и $M_r$, валентность, признаки реакций, закон сохранения массы и химические уравнения.</div>
|
||||
<div class="ch-prog">
|
||||
<div class="ch-prog-label"><span>Прогресс</span><span id="prog-1">0%</span></div>
|
||||
<div class="ch-prog-bar"><div class="ch-prog-fill" id="fill-1" style="width:0%"></div></div>
|
||||
</div>
|
||||
<div class="ch-action"><span id="btn-1">Открыть главу</span><svg class="ic" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg></div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="/textbook/chemistry-7-ch2" class="ch-card k2" id="ch-2">
|
||||
<div class="ch-cover cc2">
|
||||
<div class="ch-cover-wm">O₂</div>
|
||||
<div class="ch-num">Глава 2</div>
|
||||
<div class="ch-title">Кислород</div>
|
||||
<div class="ch-range">§13–§17 · ЛО 2 · ПР 2</div>
|
||||
</div>
|
||||
<div class="ch-body">
|
||||
<div class="ch-desc">Воздух как смесь газов, кислород — элемент и простое вещество, химические свойства кислорода и горение, оксиды, получение кислорода и катализаторы.</div>
|
||||
<div class="ch-prog">
|
||||
<div class="ch-prog-label"><span>Прогресс</span><span id="prog-2">0%</span></div>
|
||||
<div class="ch-prog-bar"><div class="ch-prog-fill" id="fill-2" style="width:0%"></div></div>
|
||||
</div>
|
||||
<div class="ch-action"><span id="btn-2">Открыть главу</span><svg class="ic" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg></div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="/textbook/chemistry-7-ch3" class="ch-card k3" id="ch-3">
|
||||
<div class="ch-cover cc3">
|
||||
<div class="ch-cover-wm">H₂</div>
|
||||
<div class="ch-num">Глава 3</div>
|
||||
<div class="ch-title">Водород</div>
|
||||
<div class="ch-range">§18–§22 · ЛО 3,4 · ПР 3</div>
|
||||
</div>
|
||||
<div class="ch-body">
|
||||
<div class="ch-desc">Водород — элемент и простое вещество, химические свойства водорода, понятие о кислотах и индикаторах, взаимодействие кислот с металлами и ряд активности, соли как продукты замещения.</div>
|
||||
<div class="ch-prog">
|
||||
<div class="ch-prog-label"><span>Прогресс</span><span id="prog-3">0%</span></div>
|
||||
<div class="ch-prog-bar"><div class="ch-prog-fill" id="fill-3" style="width:0%"></div></div>
|
||||
</div>
|
||||
<div class="ch-action"><span id="btn-3">Открыть главу</span><svg class="ic" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg></div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="/textbook/chemistry-7-ch4" class="ch-card k4" id="ch-4">
|
||||
<div class="ch-cover cc4">
|
||||
<div class="ch-cover-wm">H₂O</div>
|
||||
<div class="ch-num">Глава 4</div>
|
||||
<div class="ch-title">Вода</div>
|
||||
<div class="ch-range">§23–§26 · ЛО 5 · ПР 4</div>
|
||||
</div>
|
||||
<div class="ch-body">
|
||||
<div class="ch-desc">Состав, физические и химические свойства воды, основания как сложные вещества и индикаторы, реакция нейтрализации, охрана окружающей среды.</div>
|
||||
<div class="ch-prog">
|
||||
<div class="ch-prog-label"><span>Прогресс</span><span id="prog-4">0%</span></div>
|
||||
<div class="ch-prog-bar"><div class="ch-prog-fill" id="fill-4" style="width:0%"></div></div>
|
||||
</div>
|
||||
<div class="ch-action"><span id="btn-4">Открыть главу</span><svg class="ic" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg></div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<section class="final-wrap" id="course-final">
|
||||
<div class="final-head" id="final-head" tabindex="0" role="button" aria-expanded="false" aria-controls="final-body">
|
||||
<div class="final-head-icon">
|
||||
<svg viewBox="0 0 24 24"><path d="M7 4h10v6a5 5 0 0 1-10 0V4z"/><path d="M5 4h2v2H5a2 2 0 0 1 0-4M19 4h-2v2h2a2 2 0 0 0 0-4M9 20h6M12 15v5"/></svg>
|
||||
</div>
|
||||
<div class="final-head-text">
|
||||
<div class="final-head-tag">Финал курса</div>
|
||||
<div class="final-head-title">Босс-проверка по всему курсу</div>
|
||||
<div class="final-head-sub">Шпаргалка курса и интегрированные боссы по всем 4 главам. Победи всех — получи «Химик 7 класса».</div>
|
||||
</div>
|
||||
<div class="final-chevron"><svg viewBox="0 0 24 24"><polyline points="6 9 12 15 18 9"/></svg></div>
|
||||
</div>
|
||||
<div class="final-body" id="final-body">
|
||||
|
||||
<div class="fin-section-title"><svg viewBox="0 0 24 24"><path d="M4 6h16M4 12h16M4 18h10"/></svg> Шпаргалка курса</div>
|
||||
<div class="cheat-grid">
|
||||
<div class="cheat-card c1"><div class="cheat-head"><span class="cheat-badge">Гл. 1</span><span class="cheat-title">Первоначальные понятия</span></div><ul class="cheat-list"><li>$M_r=\sum A_r$ всех атомов</li><li>Валентность по водороду: H — I, O — II</li><li>Простое — один элемент, сложное — разные</li><li>В реакции масса сохраняется → коэффициенты</li></ul></div>
|
||||
<div class="cheat-card c2"><div class="cheat-head"><span class="cheat-badge">Гл. 2</span><span class="cheat-title">Кислород</span></div><ul class="cheat-list"><li>Воздух: $N_2$ 78 %, $O_2$ 21 %</li><li>Горение: вещество $+ O_2 \to$ оксид</li><li>Оксид — соединение элемента с O</li><li>$O_2$ из разложения (катализатор $MnO_2$)</li></ul></div>
|
||||
<div class="cheat-card c3"><div class="cheat-head"><span class="cheat-badge">Гл. 3</span><span class="cheat-title">Водород</span></div><ul class="cheat-list"><li>$H_2$ — самый лёгкий газ</li><li>Кислота = H + кислотный остаток</li><li>Ряд активности: до $H_2$ — вытесняют газ</li><li>Соль = металл + кислотный остаток</li></ul></div>
|
||||
<div class="cheat-card c4"><div class="cheat-head"><span class="cheat-badge">Гл. 4</span><span class="cheat-title">Вода</span></div><ul class="cheat-list"><li>Разложение воды: $H_2 : O_2 = 2 : 1$</li><li>Основание = металл + OH</li><li>Индикаторы: лакмус, метилоранж, фенолфталеин</li><li>Нейтрализация: кислота + основание → соль + вода</li></ul></div>
|
||||
</div>
|
||||
|
||||
<div class="fin-section-title"><svg viewBox="0 0 24 24"><path d="M14.5 3.5l-5 5L4 4l1.5 6L3 12l5 1 1 5 2.5-2.5 6 1.5-4.5-5.5 5-5"/></svg> 8 интегрированных боссов</div>
|
||||
<div class="boss-overall-bar"><div class="lab" id="fin-boss-lab">Боссов побеждено: 0 / 8</div><div class="bar"><div class="fill" id="fin-boss-fill" style="width:0%"></div></div></div>
|
||||
<div id="fin-bosses-container"></div>
|
||||
|
||||
<div class="final-cta" id="final-cta">
|
||||
<div class="final-cta-icon"><svg viewBox="0 0 24 24"><path d="M6 9H4l-1-3h18l-1 3h-2M6 9l1 6h10l1-6M6 9h12"/><path d="M9 21h6M12 15v6"/></svg></div>
|
||||
<div class="final-cta-txt"><div class="final-cta-title">Курс «Химия 7» пройден!</div><div class="final-cta-sub">Вы прошли итоговую проверку по всем 4 главам. +150 XP, ачивка «Химик 7 класса» получена.</div></div>
|
||||
<a href="/textbooks" class="final-cta-btn">К каталогу <svg viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg></a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="ach-strip" id="ach-strip">
|
||||
<div class="ach-icon">
|
||||
<svg viewBox="0 0 24 24"><path d="M6 9H4l-1-3h18l-1 3h-2M6 9l1 6h10l1-6M6 9h12"/><path d="M9 21h6M12 15v6"/></svg>
|
||||
</div>
|
||||
<div class="ach-text">
|
||||
<div class="ach-title">Химик 7 класса</div>
|
||||
<div class="ach-sub" id="ach-sub">Изучите все 26 параграфов курса, чтобы получить достижение.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
<footer class="foot">
|
||||
Интерактивный учебник «Химия — 7 класс» · LearnSpace
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
/* THEME */
|
||||
(function(){
|
||||
var saved = localStorage.getItem('chemistry7_theme') || localStorage.getItem('theme') || 'light';
|
||||
if (saved === 'dark') document.documentElement.classList.add('dark');
|
||||
var lab = document.getElementById('theme-lab');
|
||||
if (lab) lab.textContent = saved === 'dark' ? 'Светлая' : 'Тёмная';
|
||||
document.getElementById('theme-btn').addEventListener('click', function(){
|
||||
document.documentElement.classList.toggle('dark');
|
||||
var dark = document.documentElement.classList.contains('dark');
|
||||
localStorage.setItem('chemistry7_theme', dark ? 'dark' : 'light');
|
||||
localStorage.setItem('theme', dark ? 'dark' : 'light');
|
||||
if (lab) lab.textContent = dark ? 'Светлая' : 'Тёмная';
|
||||
});
|
||||
})();
|
||||
|
||||
/* PROGRESS */
|
||||
var TOTAL = 26;
|
||||
var CH_PARA = {
|
||||
'chemistry-7-ch1': 12,
|
||||
'chemistry-7-ch2': 5,
|
||||
'chemistry-7-ch3': 5,
|
||||
'chemistry-7-ch4': 4
|
||||
};
|
||||
var CH_IDX = {
|
||||
'chemistry-7-ch1': 1,
|
||||
'chemistry-7-ch2': 2,
|
||||
'chemistry-7-ch3': 3,
|
||||
'chemistry-7-ch4': 4
|
||||
};
|
||||
|
||||
function setChProg(idx, readCount, total) {
|
||||
var pct = total ? Math.min(100, Math.round(readCount * 100 / total)) : 0;
|
||||
var labelEl = document.getElementById('prog-' + idx);
|
||||
var fillEl = document.getElementById('fill-' + idx);
|
||||
var btnEl = document.getElementById('btn-' + idx);
|
||||
if (labelEl) labelEl.textContent = pct + '%';
|
||||
if (fillEl) fillEl.style.width = pct + '%';
|
||||
if (btnEl) {
|
||||
if (readCount > 0 && readCount < total) btnEl.textContent = 'Продолжить';
|
||||
else if (readCount >= total) btnEl.textContent = 'Открыть снова';
|
||||
else btnEl.textContent = 'Открыть главу';
|
||||
}
|
||||
return pct;
|
||||
}
|
||||
|
||||
var FIN_ACH_KEY = 'chemistry7_course_master';
|
||||
|
||||
function renderProgress(children) {
|
||||
var totalRead = 0;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var ch = children[i];
|
||||
var idx = CH_IDX[ch.slug];
|
||||
if (!idx) continue;
|
||||
var total = ch.para_count || CH_PARA[ch.slug] || 1;
|
||||
var read = ch.progress ? ch.progress.read.length : 0;
|
||||
if (read > total) read = total;
|
||||
totalRead += read;
|
||||
setChProg(idx, read, total);
|
||||
}
|
||||
|
||||
var pct = Math.min(100, Math.round(totalRead * 100 / TOTAL));
|
||||
var overallEl = document.getElementById('overall-text');
|
||||
var fillEl = document.getElementById('overall-fill');
|
||||
if (overallEl) overallEl.textContent = totalRead + ' из ' + TOTAL + ' параграфов \xb7 ' + pct + '%';
|
||||
if (fillEl) fillEl.style.width = pct + '%';
|
||||
|
||||
var xpBadge = document.getElementById('hero-xp-badge');
|
||||
var xp = parseInt(localStorage.getItem('chemistry7_xp') || '0', 10) || 0;
|
||||
if (xpBadge && xp > 0) {
|
||||
xpBadge.style.display = '';
|
||||
xpBadge.textContent = xp + ' XP';
|
||||
}
|
||||
|
||||
var mastered = localStorage.getItem(FIN_ACH_KEY) === '1';
|
||||
if (totalRead >= TOTAL || mastered) {
|
||||
var strip = document.getElementById('ach-strip');
|
||||
var sub = document.getElementById('ach-sub');
|
||||
if (strip) strip.classList.add('lit');
|
||||
if (sub) sub.textContent = mastered
|
||||
? 'Выполнено! Вы — Химик 7 класса.'
|
||||
: 'Выполнено! Вы изучили весь курс химии 7 класса.';
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== ФИНАЛ КУРСА: 8 интегрированных боссов ===== */
|
||||
var FIN_BOSS_KEY = 'chemistry7_course_bosses';
|
||||
var FIN_BOSSES = [
|
||||
{ n:1, tag:'Гл.1', title:'Относительная молекулярная масса', q:'Чему равна $M_r(\\text{H}_2\\text{SO}_4)$? ($A_r$: H 1, S 32, O 16)', hint:'$2\\cdot1+32+4\\cdot16=98$.', ans:98 },
|
||||
{ n:2, tag:'Гл.1', title:'Валентность', q:'Чему равна валентность серы в оксиде $\\text{SO}_2$? (кислород всегда II)', hint:'$2\\cdot\\text{II}=4$ единицы на 1 атом S → IV.', ans:4 },
|
||||
{ n:3, tag:'Гл.1', title:'Уравнение реакции', q:'В уравнении $2\\text{H}_2+\\text{O}_2=2\\text{H}_2\\text{O}$ какой коэффициент стоит перед $\\text{H}_2$?', hint:'Слева 2 молекулы водорода.', ans:2 },
|
||||
{ n:4, tag:'Гл.1', title:'Закон сохранения массы', q:'Сожгли $4$ г серы и получили $8$ г $\\text{SO}_2$. Сколько граммов кислорода вступило в реакцию?', hint:'$m(\\text{O}_2)=m(\\text{SO}_2)-m(\\text{S})=8-4$.', ans:4 },
|
||||
{ n:5, tag:'Гл.2', title:'Состав воздуха', q:'Чему примерно равна объёмная доля кислорода в воздухе (в процентах)?', hint:'Кислорода около 21 %.', ans:21 },
|
||||
{ n:6, tag:'Гл.2', title:'Оксиды', q:'Сколько атомов кислорода в формуле $\\text{Fe}_3\\text{O}_4$?', hint:'Индекс при O равен 4.', ans:4 },
|
||||
{ n:7, tag:'Гл.3', title:'Ряд активности', q:'Сколько из металлов Mg, Cu, Zn, Ag вытесняют водород из соляной кислоты?', hint:'Левее $\\text{H}_2$ стоят Mg и Zn → 2.', ans:2 },
|
||||
{ n:8, tag:'Гл.4', title:'Реакция нейтрализации', q:'В реакции $\\text{HCl}+\\text{NaOH}$ образуются соль и вода. Сколько новых веществ получилось?', hint:'$\\text{NaCl}$ и $\\text{H}_2\\text{O}$ → 2.', ans:2 }
|
||||
];
|
||||
function loadFinBossState(){ try{ return JSON.parse(localStorage.getItem(FIN_BOSS_KEY)||'{}')||{}; }catch(e){ return {}; } }
|
||||
function saveFinBossState(s){ try{ localStorage.setItem(FIN_BOSS_KEY, JSON.stringify(s)); }catch(e){} }
|
||||
function finRenderKatex(root){ if(typeof window.renderMathInElement!=='function')return; try{ window.renderMathInElement(root,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false}],throwOnError:false}); }catch(e){} }
|
||||
function updateFinBossBar(state){ var won=0; for(var k in state) if(state[k])won++; var lab=document.getElementById('fin-boss-lab'),fill=document.getElementById('fin-boss-fill'); if(lab)lab.textContent='Боссов побеждено: '+won+' / '+FIN_BOSSES.length; if(fill)fill.style.width=Math.round(won*100/FIN_BOSSES.length)+'%'; return won; }
|
||||
function maybeUnlockMaster(state){
|
||||
if(localStorage.getItem(FIN_ACH_KEY)==='1')return;
|
||||
var won=0; for(var k in state) if(state[k])won++; if(won<FIN_BOSSES.length)return;
|
||||
localStorage.setItem(FIN_ACH_KEY,'1');
|
||||
var xp=parseInt(localStorage.getItem('chemistry7_xp')||'0',10)||0; localStorage.setItem('chemistry7_xp',String(xp+150));
|
||||
try{ if(window.LS&&window.LS.xp&&window.LS.xp.add) window.LS.xp.add(150,'chemistry7-master'); }catch(e){}
|
||||
try{ if(window.confetti) window.confetti({particleCount:220,spread:110,origin:{y:.6}}); }catch(e){}
|
||||
var strip=document.getElementById('ach-strip'),sub=document.getElementById('ach-sub');
|
||||
if(strip)strip.classList.add('lit'); if(sub)sub.textContent='Выполнено! Вы — Химик 7 класса.';
|
||||
var cta=document.getElementById('final-cta'); if(cta)cta.classList.add('show');
|
||||
var xb=document.getElementById('hero-xp-badge'); if(xb){ xb.style.display=''; xb.textContent=(parseInt(localStorage.getItem('chemistry7_xp')||'0',10)||0)+' XP'; }
|
||||
}
|
||||
function buildFinBoss(b,state){
|
||||
var solved=!!state[b.n], step=b.step||'1';
|
||||
return '<div class="boss-card'+(solved?' solved':'')+'" id="fb-'+b.n+'-card">'
|
||||
+'<div class="boss-head"><span class="boss-tag">'+b.tag+'</span><span class="boss-title">Босс '+b.n+'. '+b.title+'</span></div>'
|
||||
+'<div class="boss-q">'+b.q+'</div>'
|
||||
+'<div class="boss-row"><input type="number" step="'+step+'" class="boss-input" id="fb-'+b.n+'-inp" placeholder="число"'+(solved?' value="'+b.ans+'" disabled':'')+'>'
|
||||
+'<button class="boss-btn primary" id="fb-'+b.n+'-go"'+(solved?' disabled':'')+'>Атаковать</button>'
|
||||
+'<button class="boss-btn" id="fb-'+b.n+'-hint">Подсказка</button></div>'
|
||||
+'<div class="boss-hint-txt" id="fb-'+b.n+'-ht">'+b.hint+'</div>'
|
||||
+'<div class="boss-fb'+(solved?' ok':'')+'" id="fb-'+b.n+'-fbk">'+(solved?'Победа! Босс повержен.':'')+'</div></div>';
|
||||
}
|
||||
function bindFinBoss(b){
|
||||
var go=document.getElementById('fb-'+b.n+'-go'), hint=document.getElementById('fb-'+b.n+'-hint'),
|
||||
inp=document.getElementById('fb-'+b.n+'-inp'), fbk=document.getElementById('fb-'+b.n+'-fbk'),
|
||||
ht=document.getElementById('fb-'+b.n+'-ht'), card=document.getElementById('fb-'+b.n+'-card');
|
||||
if(!go)return;
|
||||
if(hint)hint.addEventListener('click',function(){ if(ht)ht.classList.toggle('show'); });
|
||||
var state=loadFinBossState(); if(state[b.n])return;
|
||||
go.addEventListener('click',function(){
|
||||
var v=parseFloat((inp.value||'').replace(',','.'));
|
||||
if(isNaN(v)){ fbk.className='boss-fb fail'; fbk.textContent='Введите число.'; return; }
|
||||
var tol=(typeof b.tol==='number')?b.tol:1e-9;
|
||||
if(Math.abs(v-b.ans)<=tol){
|
||||
fbk.className='boss-fb ok'; fbk.textContent='Победа! +15 XP. Босс повержен.'; card.classList.add('solved'); go.disabled=true; inp.disabled=true;
|
||||
var s=loadFinBossState(); if(!s[b.n]){ s[b.n]=true; saveFinBossState(s);
|
||||
var xp=parseInt(localStorage.getItem('chemistry7_xp')||'0',10)||0; localStorage.setItem('chemistry7_xp',String(xp+15));
|
||||
try{ if(window.LS&&window.LS.xp&&window.LS.xp.add) window.LS.xp.add(15,'chemistry7-fin-boss-'+b.n); }catch(e){}
|
||||
var xb=document.getElementById('hero-xp-badge'); if(xb){ xb.style.display=''; xb.textContent=(parseInt(localStorage.getItem('chemistry7_xp')||'0',10)||0)+' XP'; }
|
||||
updateFinBossBar(s); maybeUnlockMaster(s);
|
||||
}
|
||||
} else { fbk.className='boss-fb fail'; fbk.textContent='Не то. Перепроверь решение и попробуй снова.'; }
|
||||
});
|
||||
inp.addEventListener('keydown',function(e){ if(e.key==='Enter'){ e.preventDefault(); go.click(); } });
|
||||
}
|
||||
var FIN_BOSSES_RENDERED=false;
|
||||
function renderFinBosses(){
|
||||
if(FIN_BOSSES_RENDERED)return;
|
||||
var cont=document.getElementById('fin-bosses-container'); if(!cont)return;
|
||||
var state=loadFinBossState(), html='';
|
||||
for(var i=0;i<FIN_BOSSES.length;i++) html+=buildFinBoss(FIN_BOSSES[i],state);
|
||||
cont.innerHTML=html;
|
||||
for(var j=0;j<FIN_BOSSES.length;j++) bindFinBoss(FIN_BOSSES[j]);
|
||||
finRenderKatex(document.getElementById('course-final'));
|
||||
updateFinBossBar(state);
|
||||
if(localStorage.getItem(FIN_ACH_KEY)==='1'){ var cta=document.getElementById('final-cta'); if(cta)cta.classList.add('show'); }
|
||||
FIN_BOSSES_RENDERED=true;
|
||||
}
|
||||
|
||||
/* FINAL ACCORDION */
|
||||
(function bindFinalAccordion(){
|
||||
var head = document.getElementById('final-head');
|
||||
var wrap = document.getElementById('course-final');
|
||||
if (!head || !wrap) return;
|
||||
function toggle(){
|
||||
var willOpen = !wrap.classList.contains('open');
|
||||
wrap.classList.toggle('open');
|
||||
head.setAttribute('aria-expanded', willOpen ? 'true' : 'false');
|
||||
if (willOpen) { renderFinBosses(); finRenderKatex(wrap); }
|
||||
}
|
||||
head.addEventListener('click', toggle);
|
||||
head.addEventListener('keydown', function(e){
|
||||
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggle(); }
|
||||
});
|
||||
})();
|
||||
|
||||
function loadProgress() {
|
||||
if (typeof window.LS === 'undefined' || typeof window.LS.api !== 'function') {
|
||||
renderProgress([]);
|
||||
return;
|
||||
}
|
||||
window.LS.api('/api/textbooks/chemistry-7/children')
|
||||
.then(function(data) {
|
||||
if (data && data.children) renderProgress(data.children);
|
||||
else renderProgress([]);
|
||||
})
|
||||
.catch(function() { renderProgress([]); });
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', loadProgress);
|
||||
} else {
|
||||
loadProgress();
|
||||
}
|
||||
window.addEventListener('focus', loadProgress);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user