Files
Learn_System/frontend/textbooks/chemistry_7_hub.html
T
Maxim Dolgolyov c33b4ab4f6 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>
2026-05-30 18:13:37 +03:00

541 lines
37 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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&#8341;</div>
<div class="ch-num">Глава 1</div>
<div class="ch-title">Первоначальные химические понятия</div>
<div class="ch-range">&sect;1&ndash;&sect;12 &middot; ЛО&nbsp;1 &middot; ПР&nbsp;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&#8322;</div>
<div class="ch-num">Глава 2</div>
<div class="ch-title">Кислород</div>
<div class="ch-range">&sect;13&ndash;&sect;17 &middot; ЛО&nbsp;2 &middot; ПР&nbsp;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&#8322;</div>
<div class="ch-num">Глава 3</div>
<div class="ch-title">Водород</div>
<div class="ch-range">&sect;18&ndash;&sect;22 &middot; ЛО&nbsp;3,4 &middot; ПР&nbsp;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&#8322;O</div>
<div class="ch-num">Глава 4</div>
<div class="ch-title">Вода</div>
<div class="ch-range">&sect;23&ndash;&sect;26 &middot; ЛО&nbsp;5 &middot; ПР&nbsp;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">
Интерактивный учебник &laquo;Химия &mdash; 7 класс&raquo; &middot; 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>