Files
Learn_System/frontend/textbooks/algebra_8_hub.html
T

344 lines
18 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 name="viewport" content="width=device-width,initial-scale=1.0">
<title>Алгебра 8 класс — учебник</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">
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<style>
:root{
--bg:#fdf2f8; --card:#fff;
--text:#1a1a2e; --muted:#6b5b73;
--border:#fce7f3;
--pri:#e91e63; --pri-d:#c2185b;
--pri-soft:#fce7f3;
--ch1:#e91e63; --ch1-d:#c2185b;
--ch2:#ad1457; --ch2-d:#880e4f;
--ch3:#6366f1; --ch3-d:#4f46e5;
--sh:0 4px 16px rgba(233,30,99,.09);
--sh-h:0 12px 36px rgba(233,30,99,.18);
}
html.dark{
--bg:#1a0f1a; --card:#2a1929;
--text:#f5e6f0; --muted:#b0a0b0;
--border:#5a2a5a;
--pri-soft:rgba(233,30,99,.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,#c2185b 0%,#e91e63 55%,#ec407a 100%);color:#fff;padding:32px 24px 28px;overflow:hidden;border-bottom:2px solid rgba(255,180,210,.15)}
.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(255,220,235,.10);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,.14);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,.24)}
.hdr h1{font-family:'Outfit',sans-serif;font-size:1.85rem;font-weight:900;letter-spacing:-.01em}
.hdr-sub{font-size:.92rem;opacity:.85;margin-top:4px}
.hdr-side{margin-left:auto;display:flex;gap:8px}
.hdr-btn{padding:8px 12px;background:rgba(255,255,255,.14);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,.24)}
.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}
/* INTRO */
.intro{background:var(--card);border:1px solid var(--border);border-radius:18px;padding:24px 26px;margin-bottom:28px;box-shadow:var(--sh);position:relative;overflow:hidden}
.intro::before{content:'x';position:absolute;right:-10px;top:-30px;font-size:12rem;font-style:italic;opacity:.04;line-height:1;pointer-events:none;font-family:'Inter',serif;font-weight:900;color:var(--pri-d)}
.intro h2{font-family:'Outfit',sans-serif;font-size:1.45rem;font-weight:800;color:var(--pri-d);margin-bottom:10px;letter-spacing:-.01em}
.intro p{font-size:1.02rem;color:var(--text);opacity:.9;max-width:720px;margin-bottom:8px}
.intro .meta{margin-top:14px;display:flex;gap:18px;flex-wrap:wrap;font-size:.86rem;color:var(--muted)}
.intro .meta b{color:var(--pri-d)}
/* OVERALL PROGRESS */
.prog-overall{background:linear-gradient(135deg,var(--pri-soft),rgba(99,102,241,.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,#e91e63,#6366f1);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(233,30,99,.12);border-radius:5px;overflow:hidden;margin-top:6px}
.po-fill{height:100%;background:linear-gradient(90deg,var(--pri),#6366f1);border-radius:5px;transition:width .5s}
.po-xp{display:inline-flex;align-items:center;gap:6px;padding:6px 14px;background:linear-gradient(135deg,#f59e0b,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(233,30,99,.22)}
/* CHAPTER GRID */
.ch-grid{display:grid;grid-template-columns:1fr;gap:18px;margin-bottom:30px}
@media(min-width:760px){.ch-grid{grid-template-columns:1fr 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:-10px;top:-30px;font-size:8rem;font-weight:900;font-family:'Outfit',sans-serif;line-height:1;letter-spacing:-.04em;color:rgba(255,255,255,.13);pointer-events:none}
.ch-num{display:inline-block;padding:4px 10px;background:rgba(255,255,255,.22);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.2rem;font-weight:800;letter-spacing:-.01em;position:relative;z-index:1;line-height:1.3}
.ch-range{font-size:.86rem;opacity:.85;margin-top:4px;position:relative;z-index:1;font-weight:500}
.ch-cover.ch1{background:linear-gradient(135deg,#880e4f,#e91e63 60%,#ec407a)}
.ch-cover.ch2{background:linear-gradient(135deg,#560027,#ad1457 60%,#c2185b)}
.ch-cover.ch3{background:linear-gradient(135deg,#312e81,#6366f1 60%,#818cf8)}
.ch-body{padding:18px 22px 20px;display:flex;flex-direction:column;flex:1}
.ch-desc{font-size:.9rem;color:var(--text);opacity:.82;flex:1;margin-bottom:14px;line-height:1.55}
.ch-tags{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:14px}
.ch-tag{padding:3px 9px;border-radius:6px;font-size:.72rem;font-weight:600}
.ch-tag.pink{background:var(--pri-soft);color:var(--pri-d)}
.ch-tag.indigo{background:rgba(99,102,241,.14);color:#4f46e5}
html.dark .ch-tag.indigo{color:#818cf8}
.ch-prog{margin-bottom:14px}
.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(233,30,99,.10);border-radius:4px;overflow:hidden}
.ch-prog-fill{height:100%;border-radius:4px;transition:width .5s}
.ch-card.ch1-card .ch-prog-fill{background:linear-gradient(90deg,var(--ch1),var(--ch1-d))}
.ch-card.ch2-card .ch-prog-fill{background:linear-gradient(90deg,var(--ch2),var(--ch2-d))}
.ch-card.ch3-card .ch-prog-fill{background:linear-gradient(90deg,var(--ch3),var(--ch3-d))}
.ch-action{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-radius:11px;font-weight:700;font-size:.92rem;color:#fff;transition:filter .15s}
.ch-action:hover{filter:brightness(1.08)}
.ch-card.ch1-card .ch-action{background:linear-gradient(135deg,var(--ch1),#ec407a)}
.ch-card.ch2-card .ch-action{background:linear-gradient(135deg,var(--ch2),#d81b60)}
.ch-card.ch3-card .ch-action{background:linear-gradient(135deg,var(--ch3),#818cf8)}
/* 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:#f59e0b;box-shadow:0 0 0 3px rgba(245,158,11,.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,#fbbf24,#f59e0b)}
.ach-icon svg{width:28px;height:28px;stroke:var(--muted)}
.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:#92400e}
.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>Алгебра — 8 класс</h1>
<div class="hdr-sub">Полный курс: корни, уравнения, неравенства</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">x</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">0 XP</div>
</section>
<div class="ch-grid">
<a href="/textbook/algebra-8-ch1" class="ch-card ch1-card" id="ch-1">
<div class="ch-cover ch1">
<div class="ch-cover-wm">I</div>
<div class="ch-num">Глава 1</div>
<div class="ch-title">Квадратные корни. Действительные числа</div>
<div class="ch-range">§1–§6 + Финал</div>
</div>
<div class="ch-body">
<div class="ch-desc">Понятие квадратного корня, арифметический корень, свойства квадратных корней, упрощение выражений с корнями, числовые неравенства, действительные числа.</div>
<div class="ch-tags">
<span class="ch-tag pink">Корни</span>
<span class="ch-tag pink">Иррациональность</span>
<span class="ch-tag pink">6 параграфов</span>
</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/algebra-8-ch2" class="ch-card ch2-card" id="ch-2">
<div class="ch-cover ch2">
<div class="ch-cover-wm">II</div>
<div class="ch-num">Глава 2</div>
<div class="ch-title">Квадратные уравнения</div>
<div class="ch-range">§7–§12 + Финал</div>
</div>
<div class="ch-body">
<div class="ch-desc">Квадратные уравнения и их решение, формула дискриминанта, теорема Виета, уравнения, сводимые к квадратным, задачи на составление уравнений.</div>
<div class="ch-tags">
<span class="ch-tag pink">Дискриминант</span>
<span class="ch-tag pink">Теорема Виета</span>
<span class="ch-tag pink">7 параграфов</span>
</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/algebra-8-ch3" class="ch-card ch3-card" id="ch-3">
<div class="ch-cover ch3">
<div class="ch-cover-wm">III</div>
<div class="ch-num">Глава 3</div>
<div class="ch-title">Неравенства с одной переменной</div>
<div class="ch-range">§13–§18 + Финал</div>
</div>
<div class="ch-body">
<div class="ch-desc">Числовые неравенства, линейные неравенства с одной переменной, системы и совокупности неравенств, метод интервалов, квадратные неравенства.</div>
<div class="ch-tags">
<span class="ch-tag indigo">Метод интервалов</span>
<span class="ch-tag indigo">Системы</span>
<span class="ch-tag indigo">7 параграфов</span>
</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>
</div>
<div class="ach-strip" id="ach-strip">
<div class="ach-icon">
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<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">Магистр алгебры 8</div>
<div class="ach-sub" id="ach-sub">Прочитайте все 21 параграф трёх глав, чтобы получить достижение</div>
</div>
</div>
</main>
<footer class="foot">
Интерактивный учебник «Алгебра — 8 класс» · LearnSpace
</footer>
<script>
'use strict';
/* THEME */
(function(){
const saved = localStorage.getItem('algebra8_theme') || localStorage.getItem('theme') || 'light';
if (saved === 'dark') document.documentElement.classList.add('dark');
const lab = document.getElementById('theme-lab');
if (lab) lab.textContent = saved === 'dark' ? 'Светлая' : 'Тёмная';
document.getElementById('theme-btn').addEventListener('click', function(){
document.documentElement.classList.toggle('dark');
const dark = document.documentElement.classList.contains('dark');
localStorage.setItem('algebra8_theme', dark ? 'dark' : 'light');
localStorage.setItem('theme', dark ? 'dark' : 'light');
if (lab) lab.textContent = dark ? 'Светлая' : 'Тёмная';
});
})();
/* PROGRESS — loaded from /api/textbooks/algebra-8/children via LS.api */
var TOTAL = 21;
/* Para counts per chapter (slugs algebra-8-ch1/ch2/ch3) */
var CH_PARA = { 'algebra-8-ch1': 7, 'algebra-8-ch2': 7, 'algebra-8-ch3': 7 };
/* Map slug to card index 1/2/3 */
var CH_IDX = { 'algebra-8-ch1': 1, 'algebra-8-ch2': 2, 'algebra-8-ch3': 3 };
function setChProg(idx, readCount, total) {
var pct = total ? 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;
}
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 read = ch.progress ? ch.progress.read.length : 0;
var total = ch.para_count || CH_PARA[ch.slug] || 7;
totalRead += read;
setChProg(idx, read, total);
}
var pct = Math.round(totalRead * 100 / TOTAL);
var overallEl = document.getElementById('overall-text');
var fillEl = document.getElementById('overall-fill');
if (overallEl) overallEl.textContent = totalRead + ' из ' + TOTAL + ' параграфов · ' + pct + '%';
if (fillEl) fillEl.style.width = pct + '%';
/* Achievement strip */
if (totalRead >= TOTAL) {
var strip = document.getElementById('ach-strip');
var sub = document.getElementById('ach-sub');
if (strip) strip.classList.add('lit');
if (sub) sub.textContent = 'Выполнено! Вы прочитали весь курс алгебры 8 класса.';
}
}
function loadProgress() {
/* Requires LS.api (window.LS from /js/api.js). Signature: LS.api(path, fetchOptions?) */
if (typeof window.LS === 'undefined' || typeof window.LS.api !== 'function') {
/* Not authenticated: show zeros */
renderProgress([]);
return;
}
window.LS.api('/api/textbooks/algebra-8/children')
.then(function(data) {
if (data && data.children) renderProgress(data.children);
else renderProgress([]);
})
.catch(function() { renderProgress([]); });
}
/* Wait for api.js to be ready */
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', loadProgress);
} else {
loadProgress();
}
window.addEventListener('focus', loadProgress);
</script>
</body>
</html>