feat(phys11 W0): инфра — миграция БД, phys-fx.js, hub + 8 stub-глав

Миграция 031_physics_11_hub.sql:
- hub textbook 'physics-11' (cyan, sort 12, para_count 45)
- 8 children по главам: ch1 cyan, ch2 violet, ch3 amber, ch4 blue,
  ch5 pink, ch6 green, ch7 rose, ch8 indigo

frontend/js/phys-fx.js (~360 строк):
- Глобальный requestAnimationFrame-цикл (Ticker) с подписками
- util.subscribe/unsubscribe + IntersectionObserver-пауза невидимых
- util.svgFrame, util.axes, util.slider — общие хелперы
- PHYS.Oscillogram: гарм. колебания с амплитудой/частотой/фазой/затуханием
- PHYS.SpringMass: пружинный маятник (T=2π√(m/k)) с зигзаг-пружиной
- PHYS.Pendulum: математический маятник (T=2π√(l/g)) с дугой

frontend/textbooks/physics_11_hub.html:
- Header cyan-gradient + watermark ФИЗИКА
- 4-кол grid карточек глав (8 шт., responsive)
- Прогресс-бар курса + API /api/textbooks/physics-11/children

frontend/textbooks/physics_11_ch1..ch8.html:
- Stub-страницы по образцу geometry_10_r1..r4 (W0)
- Список параграфов с ключевыми формулами + 'Будет добавлено в волне WN'
- Каждая глава со своей темой (gradient, watermark, цветами)
- phys-fx.js подключён сразу (ready для W1+)

backend/scripts/gen_phys11_stubs.js — генератор для повторных сборок.
This commit is contained in:
Maxim Dolgolyov
2026-05-29 17:42:36 +03:00
parent 774b54afc8
commit 22b95ed072
12 changed files with 2569 additions and 0 deletions
+463
View File
@@ -0,0 +1,463 @@
#!/usr/bin/env node
'use strict';
/* Генератор stub-файлов для Физики 11 (W0).
* Запуск: node backend/scripts/gen_phys11_stubs.js
*/
const fs = require('fs');
const path = require('path');
const OUT = path.join(__dirname, '..', '..', 'frontend', 'textbooks');
const CHAPTERS = [
{ n:1, slug:'physics-11-ch1', name:'Механические колебания и волны',
paraRange:'§1–§6', wm:'∿', themeName:'cyan',
gradient:['#155e75','#0891b2','#a5f3fc'],
pri:'#0891b2', pri2:'#0e7490', priSoft:'#cffafe',
desc:'Колебательное движение, гармонические колебания, маятники, превращения энергии, резонанс, продольные и поперечные волны, звук.',
paras:[
{n:1, title:'Колебательное движение. Гармонические колебания', sub:'$T = \\Delta t / N$, $\\nu = 1/T$, $\\omega = 2\\pi/T$, $x = A\\cos(\\omega t + \\varphi_0)$'},
{n:2, title:'Пружинный и математический маятники', sub:'$T_{пр} = 2\\pi\\sqrt{m/k}$, $T_{мат} = 2\\pi\\sqrt{l/g}$'},
{n:3, title:'Превращения энергии при гарм. колебаниях', sub:'$W_{мех} = kA^2/2 = m\\omega^2 A^2/2$'},
{n:4, title:'Свободные и вынужденные колебания. Резонанс', sub:'Затухание, диссипация, $\\omega_{рез} \\approx \\omega_0$'},
{n:5, title:'Распространение колебаний в упругой среде. Продольные и поперечные волны', sub:'$\\lambda = vT$'},
{n:6, title:'Звуковые волны', sub:'16 Гц 20 кГц, $v_{зв}^{возд} \\approx 340$ м/с'}
]
},
{ n:2, slug:'physics-11-ch2', name:'Электромагнитные колебания и волны',
paraRange:'§7–§13', wm:'⚡', themeName:'violet',
gradient:['#5b21b6','#7c3aed','#c4b5fd'],
pri:'#7c3aed', pri2:'#5b21b6', priSoft:'#ede9fe',
desc:'Колебательный контур, формула Томсона, переменный ток, трансформатор, передача электроэнергии, ЭМ волны.',
paras:[
{n:7, title:'Колебательный контур. Свободные ЭМ колебания. Формула Томсона', sub:'$T = 2\\pi\\sqrt{LC}$'},
{n:8, title:'Вынужденные ЭМ колебания. Переменный ток', sub:'$i = I_0\\sin(\\omega t)$, $I = I_0/\\sqrt{2}$'},
{n:9, title:'Преобразование переменного тока. Трансформатор', sub:'$k = N_1/N_2 = U_1/U_2$'},
{n:10, title:'Производство, передача и потребление электроэнергии', sub:'ГЭС, ТЭС, АЭС; потери $P = I^2 R$'},
{n:11, title:'Экологические проблемы производства и передачи электроэнергии', sub:'ВЭС, СЭС, гео- и приливные'},
{n:12, title:'ЭМ волны. Шкала ЭМ волн', sub:'$c = 3 \\cdot 10^8$ м/с'},
{n:13, title:'Действие ЭМ излучения на живые организмы', sub:'Ионизирующее vs неионизирующее'}
]
},
{ n:3, slug:'physics-11-ch3', name:'Оптика',
paraRange:'§14–§23', wm:'◇', themeName:'amber',
gradient:['#b45309','#d97706','#fcd34d'],
pri:'#d97706', pri2:'#b45309', priSoft:'#fef3c7',
desc:'Электромагнитная природа света, интерференция, дифракция, отражение, зеркала, преломление, тонкая линза, оптические приборы.',
paras:[
{n:14, title:'ЭМ природа света. Скорость света', sub:'Опыты Рёмера, Майкельсона'},
{n:15, title:'Интерференция света', sub:'$\\Delta = k\\lambda$ (max), $\\Delta = (2k+1)\\lambda/2$ (min)'},
{n:16, title:'Принцип Гюйгенса – Френеля. Дифракция. Дифракционная решётка', sub:'$d\\sin\\varphi = k\\lambda$'},
{n:17, title:'Прямолинейное распространение и отражение света. Зеркала', sub:'$\\angle_{пад} = \\angle_{отр}$'},
{n:18, title:'Сферические зеркала. Построение изображений', sub:'$\\frac{1}{F} = \\frac{1}{d} + \\frac{1}{f}$'},
{n:19, title:'Закон преломления света. Полное отражение', sub:'$n_1\\sin\\alpha = n_2\\sin\\beta$, $\\sin\\alpha_{пр} = 1/n$'},
{n:20, title:'Прохождение света через оптические элементы', sub:'Призмы, оптоволокно'},
{n:21, title:'Формула тонкой линзы', sub:'$D = 1/F$, $\\Gamma = f/d$'},
{n:22, title:'Оптические приборы для действительных изображений', sub:'Фотоаппарат, проектор'},
{n:23, title:'Оптические приборы для увеличения угла зрения', sub:'Лупа, микроскоп, телескоп'}
]
},
{ n:4, slug:'physics-11-ch4', name:'Основы СТО',
paraRange:'§24–§26', wm:'c', themeName:'blue',
gradient:['#1e3a8a','#2563eb','#93c5fd'],
pri:'#2563eb', pri2:'#1d4ed8', priSoft:'#dbeafe',
desc:'Принцип относительности Галилея, постулаты Эйнштейна, преобразования Лоренца, релятивистская динамика, E=mc².',
paras:[
{n:24, title:'Принцип относ. Галилея и ЭМ явления. Эксп. предпосылки СТО', sub:'Опыт Майкельсона – Морли'},
{n:25, title:'Постулаты специальной теории относительности', sub:'$\\Delta t = \\gamma\\Delta t_0$, $l = l_0/\\gamma$'},
{n:26, title:'Элементы релятивистской динамики. Взаимосвязь массы и энергии', sub:'$E_0 = mc^2$, $E^2 = (mc^2)^2 + (pc)^2$'}
]
},
{ n:5, slug:'physics-11-ch5', name:'Фотоны. Действия света',
paraRange:'§27–§29', wm:'γ', themeName:'pink',
gradient:['#831843','#db2777','#fbcfe8'],
pri:'#db2777', pri2:'#9d174d', priSoft:'#fce7f3',
desc:'Фотоэффект, квантовая гипотеза Планка, фотон, уравнение Эйнштейна, давление света, корпускулярно-волновой дуализм.',
paras:[
{n:27, title:'Фотоэффект. Эксперим. законы. Квантовая гипотеза Планка', sub:'$E = h\\nu$, $h = 6{,}63 \\cdot 10^{-34}$ Дж·с'},
{n:28, title:'Фотон. Уравнение Эйнштейна для фотоэффекта', sub:'$h\\nu = A_{вых} + \\frac{mv_{max}^2}{2}$'},
{n:29, title:'Давление света. Корпускулярно-волновой дуализм', sub:'$p_{фот} = h\\nu/c$. Опыт Лебедева'}
]
},
{ n:6, slug:'physics-11-ch6', name:'Физика атома',
paraRange:'§30–§34', wm:'⚛', themeName:'emerald',
gradient:['#065f46','#10b981','#a7f3d0'],
pri:'#10b981', pri2:'#047857', priSoft:'#d1fae5',
desc:'Ядерная модель атома Резерфорда, квантовые постулаты Бора, спектры испускания и поглощения, лазеры.',
paras:[
{n:30, title:'Сложное строение атома. Ядерная модель атома', sub:'Опыт Резерфорда, размер ядра $\\sim 10^{-15}$ м'},
{n:31, title:'Квантовые постулаты Бора', sub:'$E_n = -E_1/n^2 = -13{,}6/n^2$ эВ'},
{n:32, title:'Излучение и поглощение света атомом. Спектры', sub:'$h\\nu = E_n - E_m$, линейчатые спектры'},
{n:33, title:'Спонтанное и индуцированное излучение', sub:'Подготовка к лазерам'},
{n:34, title:'Лазеры', sub:'Инверсная населённость, когерентность'}
]
},
{ n:7, slug:'physics-11-ch7', name:'Ядерная физика и элементарные частицы',
paraRange:'§35–§44', wm:'☢', themeName:'rose',
gradient:['#7f1d1d','#dc2626','#fca5a5'],
pri:'#dc2626', pri2:'#991b1b', priSoft:'#fee2e2',
desc:'Протонно-нейтронная модель ядра, ядерные реакции, энергия связи, радиоактивность, ядерный реактор, термояд, элементарные частицы.',
paras:[
{n:35, title:'Протонно-нейтронная модель строения ядра атома', sub:'$A = Z + N$, изотопы'},
{n:36, title:'Ядерные реакции. Законы сохранения в ядерных реакциях', sub:'Сохранение заряда, нуклонов, энергии'},
{n:37, title:'Энергия связи ядра атома', sub:'$E_{св} = \\Delta m \\cdot c^2$, $\\Delta m = Zm_p + Nm_n - m_я$'},
{n:38, title:'Радиоактивность', sub:'$\\alpha$, $\\beta$, $\\gamma$ распады'},
{n:39, title:'Закон радиоактивного распада', sub:'$N = N_0 \\cdot 2^{-t/T}$, период полураспада $T$'},
{n:40, title:'Деление тяжёлых ядер. Цепные ядерные реакции', sub:'$^{235}$U, $k$ — коэф. размножения'},
{n:41, title:'Ядерный реактор', sub:'Управляющие стержни, замедлитель'},
{n:42, title:'Реакции ядерного синтеза', sub:'Термояд, $^2$H + $^3$H $\\to ^4$He + n'},
{n:43, title:'Ионизирующее излучение. Элементы дозиметрии', sub:'Доза $D$, эквивалент $H$, зиверт'},
{n:44, title:'Элементарные частицы и их взаимодействия', sub:'Стандартная модель, 4 фундаментальных взаимодействия'}
]
},
{ n:8, slug:'physics-11-ch8', name:'Основы единой физической картины мира',
paraRange:'§45', wm:'∞', themeName:'indigo',
gradient:['#3730a3','#6366f1','#c7d2fe'],
pri:'#6366f1', pri2:'#4338ca', priSoft:'#e0e7ff',
desc:'Современная естественнонаучная картина мира, эволюция физических теорий, четыре фундаментальных взаимодействия.',
paras:[
{n:45, title:'Современная естественнонаучная картина мира', sub:'Эволюция представлений: механика → ЭМ → квант'}
]
}
];
function makeChapter(c){
/* В какой волне будет реализована эта глава (см. PLAN_FIZIKA_11.md) */
const waveOf = {1:'W1-W2', 2:'W3-W4', 3:'W5-W7', 4:'W8', 5:'W9', 6:'W10-W11', 7:'W12-W13', 8:'W14'};
const wave = waveOf[c.n] || 'W1+';
const parasHtml = c.paras.map(p => `
<article class="para-card">
<div class="para-num">§ ${p.n}</div>
<div class="para-body">
<h2 class="para-title">${p.title}</h2>
<p class="para-sub">${p.sub}</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне ${wave}
</div>
</div>
</article>`).join('\n');
return `<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Физика 11 · Глава ${c.n} · ${c.name}</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"
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\\\[',right:'\\\\]',display:true},{left:'\\\\(',right:'\\\\)',display:false}],throwOnError:false})"></script>
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<script src="/js/phys-fx.js?v=1" defer></script>
<style>
:root{
--bg:#f8fafc; --card:#fff;
--text:#0f172a; --muted:#475569;
--border:#e2e8f0;
--pri:${c.pri}; --pri-d:${c.pri2};
--pri-soft:${c.priSoft};
--dark:${c.gradient[0]};
--sh:0 4px 16px rgba(0,0,0,.06);
}
html.dark{
--bg:#020617; --card:#0a1929;
--text:#dbeafe; --muted:#94a3b8;
--border:#1e293b;
}
*{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}
.hdr{position:relative;background:linear-gradient(110deg,${c.gradient[0]} 0%,${c.gradient[1]} 55%,${c.gradient[2]} 100%);color:#fff;padding:32px 24px 28px;overflow:hidden}
.hdr::before{content:'${c.wm}';position:absolute;right:8px;top:-20%;font-family:'Outfit',sans-serif;font-size:clamp(8rem,22vw,18rem);font-weight:900;color:rgba(255,255,255,.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.7rem;font-weight:900;letter-spacing:-.01em}
.hdr-sub{font-size:.92rem;opacity:.85;margin-top:4px}
.ic{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
main{max-width:980px;margin:0 auto;padding:32px 24px 60px}
.intro-card{background:var(--card);border:1.5px solid var(--border);border-radius:16px;padding:22px 26px;margin-bottom:28px;box-shadow:var(--sh)}
.intro-num{display:inline-block;padding:4px 10px;background:var(--pri-soft);color:var(--pri-d);border-radius:99px;font-size:.72rem;font-weight:800;letter-spacing:.06em;margin-bottom:8px;text-transform:uppercase}
.intro-card h2{font-family:'Outfit',sans-serif;font-size:1.4rem;font-weight:800;margin-bottom:6px}
.intro-card p{color:var(--muted);font-size:.95rem}
.para-grid{display:grid;grid-template-columns:1fr;gap:14px}
.para-card{background:var(--card);border:1.5px solid var(--border);border-radius:14px;padding:18px 20px;display:flex;gap:16px;align-items:flex-start;transition:transform .15s,box-shadow .15s,border-color .15s}
.para-card:hover{transform:translateY(-2px);box-shadow:var(--sh);border-color:var(--pri)}
.para-num{font-family:'Outfit',sans-serif;font-size:1rem;font-weight:900;color:#fff;background:linear-gradient(135deg,var(--pri),var(--pri-d));padding:8px 12px;border-radius:9px;min-width:56px;text-align:center;letter-spacing:-.02em;flex-shrink:0}
.para-body{flex:1}
.para-title{font-family:'Outfit',sans-serif;font-size:1.05rem;font-weight:800;margin-bottom:4px;color:var(--text)}
.para-sub{font-size:.88rem;color:var(--muted);margin-bottom:10px;line-height:1.55}
.para-status{display:inline-flex;align-items:center;gap:6px;font-size:.78rem;color:var(--muted);background:rgba(0,0,0,.04);padding:6px 10px;border-radius:8px;font-weight:600}
html.dark .para-status{background:rgba(255,255,255,.06)}
.para-status .ic{width:14px;height:14px}
.banner-soon{margin-top:30px;text-align:center;padding:20px;background:linear-gradient(135deg,var(--pri-soft),transparent);border:1px dashed var(--pri);border-radius:14px;color:var(--pri-d);font-weight:700;font-size:.92rem}
.banner-soon b{font-family:'Outfit',sans-serif}
.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="/textbook/physics-11" class="hdr-back">
<svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
К курсу физики 11
</a>
</div>
<div>
<h1>Глава ${c.n}. ${c.name}</h1>
<div class="hdr-sub">${c.desc.split('.')[0]} · ${c.paraRange}</div>
</div>
</div>
</header>
<main>
<div class="intro-card">
<span class="intro-num">Глава ${c.n}</span>
<h2>${c.name}</h2>
<p>${c.desc} Глава содержит ${c.paras.length} параграф${c.paras.length === 1 ? '' : (c.paras.length < 5 ? 'а' : 'ов')} и финальный этап с боссами.</p>
</div>
<div class="para-grid">
${parasHtml}
</div>
<div class="banner-soon">
<b>Глава в разработке.</b> Полная реализация — в следующих волнах. Базовая библиотека <code>phys-fx.js</code> уже доступна.
</div>
</main>
<footer class="foot">
Физика — 11 класс · Глава ${c.n} · LearnSpace
</footer>
</body>
</html>
`;
}
function makeHub(){
const cards = CHAPTERS.map((c, i) => `
<a href="/textbook/${c.slug}" class="ch-card" style="--ch:${c.pri};--ch-d:${c.pri2};--ch-soft:${c.priSoft}">
<div class="ch-cover" style="background:linear-gradient(135deg,${c.gradient[0]},${c.gradient[1]} 60%,${c.gradient[2]})">
<div class="ch-cover-wm">${c.wm}</div>
<div class="ch-num">Глава ${c.n}</div>
<div class="ch-title">${c.name}</div>
<div class="ch-range">${c.paraRange} + Финал</div>
</div>
<div class="ch-body">
<div class="ch-desc">${c.desc}</div>
<div class="ch-prog">
<div class="ch-prog-label"><span>Прогресс</span><span id="prog-${c.n}">0%</span></div>
<div class="ch-prog-bar"><div class="ch-prog-fill" id="fill-${c.n}" style="width:0%"></div></div>
</div>
<div class="ch-action">
<span id="btn-${c.n}">Открыть главу</span>
<svg class="ic" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
</div>
</div>
</a>`).join('\n');
return `<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Физика 11 класс — учебник</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"
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\\\[',right:'\\\\]',display:true},{left:'\\\\(',right:'\\\\)',display:false}],throwOnError:false})"></script>
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<style>
:root{
--bg:#ecfeff; --card:#fff;
--text:#0f172a; --muted:#475569;
--border:#a5f3fc;
--pri:#0891b2; --pri-d:#0e7490;
--pri-soft:#cffafe;
--sh:0 4px 16px rgba(8,145,178,.10);
--sh-h:0 12px 36px rgba(8,145,178,.18);
}
html.dark{
--bg:#062326; --card:#0a2e35;
--text:#cffafe; --muted:#67e8f9;
--border:#0f4750;
}
*{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}
.hdr{position:relative;background:linear-gradient(110deg,#155e75 0%,#0891b2 55%,#67e8f9 100%);color:#fff;padding:32px 24px 28px;overflow:hidden;border-bottom:2px solid rgba(165,243,252,.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(207,250,254,.12);line-height:1;pointer-events:none;user-select:none}
.hdr-inner{position:relative;z-index:1;max-width:1180px;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:.88;margin-top:4px}
.ic{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
main{max-width:1180px;margin:0 auto;padding:32px 24px 60px}
.prog-overall{background:linear-gradient(135deg,var(--pri-soft),rgba(103,232,249,.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,#0891b2,#67e8f9);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(8,145,178,.14);border-radius:5px;overflow:hidden;margin-top:6px}
.po-fill{height:100%;background:linear-gradient(90deg,var(--pri),#67e8f9);border-radius:5px;transition:width .5s}
.ch-grid{display:grid;grid-template-columns:1fr;gap:18px;margin-bottom:30px}
@media(min-width:680px){.ch-grid{grid-template-columns:1fr 1fr}}
@media(min-width:1100px){.ch-grid{grid-template-columns:repeat(4,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:-8px;top:-22px;font-size:5.2rem;font-weight:900;font-family:'Outfit',sans-serif;line-height:1;color:rgba(255,255,255,.20);pointer-events:none;letter-spacing:-.04em}
.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.05rem;font-weight:800;letter-spacing:-.01em;position:relative;z-index:1;line-height:1.3}
.ch-range{font-size:.82rem;opacity:.88;margin-top:4px;position:relative;z-index:1;font-weight:500}
.ch-body{padding:16px 20px 18px;display:flex;flex-direction:column;flex:1}
.ch-desc{font-size:.86rem;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;background:linear-gradient(90deg,var(--ch),var(--ch-d));transition:width .5s}
.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;background:linear-gradient(135deg,var(--ch),var(--ch-d));transition:filter .15s}
.ch-action:hover{filter:brightness(1.08)}
.banner-soon{margin-top:18px;text-align:center;padding:20px;background:linear-gradient(135deg,var(--pri-soft),transparent);border:1px dashed var(--pri);border-radius:14px;color:var(--pri-d);font-weight:700;font-size:.92rem}
.banner-soon b{font-family:'Outfit',sans-serif;display:block;margin-bottom:4px;font-size:1.05rem}
.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>Физика — 11 класс</h1>
<div class="hdr-sub">Жилко · Маркович · Сокольский (2021) · 8 глав · 45 параграфов</div>
</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>
</section>
<div class="ch-grid">
${cards}
</div>
<div class="banner-soon">
<b>Курс в активной разработке (W0)</b>
Инфраструктура готова: миграция БД, библиотека phys-fx.js (Oscillogram, SpringMass, Pendulum) и 8 stub-страниц глав. Реализация по плану PLAN_FIZIKA_11.md — 15 волн (~26 сессий).
</div>
</main>
<footer class="foot">
Интерактивный учебник «Физика — 11 класс» · LearnSpace
</footer>
<script>
'use strict';
var TOTAL = 45;
var CH_PARA = {${CHAPTERS.map(c => "'" + c.slug + "': " + c.paras.length).join(', ')}};
var CH_IDX = {${CHAPTERS.map(c => "'" + c.slug + "': " + c.n).join(', ')}};
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 = 'Открыть главу';
}
}
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] || 1;
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 + '%';
}
function loadProgress(){
if (typeof window.LS === 'undefined' || typeof window.LS.api !== 'function'){
renderProgress([]); return;
}
window.LS.api('/api/textbooks/physics-11/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>
`;
}
/* Write all 9 files */
fs.writeFileSync(path.join(OUT, 'physics_11_hub.html'), makeHub(), 'utf8');
console.log('Wrote: physics_11_hub.html');
CHAPTERS.forEach(c => {
const fname = 'physics_11_ch' + c.n + '.html';
fs.writeFileSync(path.join(OUT, fname), makeChapter(c), 'utf8');
console.log('Wrote:', fname);
});
console.log('Done. 9 stub files generated.');
@@ -0,0 +1,48 @@
-- Physics 11 hub migration.
-- Adds hub row + 8 chapter children for Физика 11 (Жилко/Маркович/Сокольский, 2021).
-- Pattern mirrors 030_physics_10_hub.sql.
-- 1. Hub row.
INSERT INTO textbooks
(slug, subject, grade, title, author, description, html_path, para_count, color, sort_order, is_active)
VALUES
('physics-11', 'physics', 11, 'Физика — 11 класс', '',
'Полный курс физики 11 класса по учебнику Жилко-Маркович-Сокольского: механические и электромагнитные колебания и волны, оптика, основы СТО, фотоны, физика атома, ядерная физика и элементарные частицы, единая физическая картина мира. 8 глав, 45 параграфов, реальные симуляции через библиотеку phys-fx.js (анимации, маятники, контуры, лучевые трассировщики, спектры, ядро).',
'physics_11_hub.html', 45, 'cyan', 12, 1);
-- 2. Chapter children.
INSERT INTO textbooks
(slug, subject, grade, title, author, description, html_path, para_count, color, sort_order, is_active, parent_slug)
VALUES
('physics-11-ch1', 'physics', 11, 'Физика 11 · Механические колебания и волны',
'',
'§1–§6: колебательное движение, гармонические колебания, пружинный и математический маятники, превращения энергии при гармонических колебаниях, свободные и вынужденные колебания, резонанс, распространение колебаний в упругой среде, продольные и поперечные волны, звуковые волны.',
'physics_11_ch1.html', 6, 'cyan', 1, 1, 'physics-11'),
('physics-11-ch2', 'physics', 11, 'Физика 11 · Электромагнитные колебания и волны',
'',
'§7–§13: колебательный контур, свободные электромагнитные колебания, формула Томсона, вынужденные ЭМ колебания, переменный электрический ток, трансформатор, производство и передача электроэнергии, ЭМ волны и их свойства, шкала ЭМ волн, действие ЭМ излучения на живые организмы.',
'physics_11_ch2.html', 7, 'violet', 2, 1, 'physics-11'),
('physics-11-ch3', 'physics', 11, 'Физика 11 · Оптика',
'',
'§14–§23: электромагнитная природа света, скорость света, интерференция, принцип Гюйгенса-Френеля, дифракция, дифракционная решётка, отражение света, зеркала плоские и сферические, закон преломления, полное отражение, прохождение света через оптические элементы, формула тонкой линзы, оптические приборы.',
'physics_11_ch3.html', 10, 'amber', 3, 1, 'physics-11'),
('physics-11-ch4', 'physics', 11, 'Физика 11 · Основы СТО',
'',
'§24–§26: принцип относительности Галилея, экспериментальные предпосылки СТО, постулаты Эйнштейна, преобразования Лоренца, релятивистская динамика, взаимосвязь массы и энергии E=mc².',
'physics_11_ch4.html', 3, 'blue', 4, 1, 'physics-11'),
('physics-11-ch5', 'physics', 11, 'Физика 11 · Фотоны. Действия света',
'',
'§27–§29: фотоэффект, экспериментальные законы внешнего фотоэффекта, квантовая гипотеза Планка, фотон, уравнение Эйнштейна для фотоэффекта, давление света, корпускулярно-волновой дуализм.',
'physics_11_ch5.html', 3, 'pink', 5, 1, 'physics-11'),
('physics-11-ch6', 'physics', 11, 'Физика 11 · Физика атома',
'',
'§30–§34: явления, подтверждающие сложное строение атома, ядерная модель атома Резерфорда, квантовые постулаты Бора, излучение и поглощение света атомом, спектры испускания и поглощения, спонтанное и индуцированное излучение, лазеры.',
'physics_11_ch6.html', 5, 'green', 6, 1, 'physics-11'),
('physics-11-ch7', 'physics', 11, 'Физика 11 · Ядерная физика и элементарные частицы',
'',
'§35–§44: протонно-нейтронная модель ядра, ядерные реакции, законы сохранения, энергия связи ядра, радиоактивность, закон радиоактивного распада, деление тяжёлых ядер, цепные ядерные реакции, ядерный реактор, реакции ядерного синтеза, ионизирующее излучение, дозиметрия, элементарные частицы и их взаимодействия.',
'physics_11_ch7.html', 10, 'rose', 7, 1, 'physics-11'),
('physics-11-ch8', 'physics', 11, 'Физика 11 · Основы единой физической картины мира',
'',
'§45: современная естественнонаучная картина мира, физическая картина мира, четыре фундаментальных взаимодействия, эволюция представлений о природе.',
'physics_11_ch8.html', 1, 'indigo', 8, 1, 'physics-11');
+324
View File
@@ -0,0 +1,324 @@
/* phys-fx.js — библиотека анимированных физических симуляций для Физики 11.
*
* Архитектура:
* - Один глобальный requestAnimationFrame-цикл (Ticker).
* - Каждая симуляция — класс с методами update(dt, t), render().
* - IntersectionObserver: симуляция приостанавливается, когда уходит из viewport.
* - Чистый SVG (без Canvas, без WebGL, без зависимостей).
*
* Публичный API: window.PHYS = { util, Oscillogram, SpringMass, Pendulum, ... }.
*
* W0 — базовая инфраструктура + 3 компонента (Oscillogram, SpringMass, Pendulum).
* Расширяется в W3 (электротехника), W5-W7 (оптика), W9-W14 (кванты, ядро).
*/
(function(){
'use strict';
if (window.PHYS && window.PHYS.__installed) return;
const P = window.PHYS = window.PHYS || {};
P.__installed = true;
/* ============================================================ */
/* ГЛОБАЛЬНЫЙ ТАЙМЕР (один RAF на всю страницу) */
/* ============================================================ */
const Ticker = {
t: 0,
last: 0,
subs: new Set(),
running: false
};
function tick(ts){
if (!Ticker.running) return;
if (!Ticker.last) Ticker.last = ts;
const dt = Math.min((ts - Ticker.last) / 1000, 0.1); // защита от лагов
Ticker.last = ts;
Ticker.t += dt;
Ticker.subs.forEach(s => {
if (!s.paused) {
try { s.update(dt, Ticker.t); s.render && s.render(); }
catch(e) {}
}
});
requestAnimationFrame(tick);
}
function startTicker(){
if (Ticker.running) return;
Ticker.running = true;
Ticker.last = 0;
requestAnimationFrame(tick);
}
function stopTicker(){ Ticker.running = false; }
/* ============================================================ */
/* УТИЛИТЫ */
/* ============================================================ */
const util = P.util = {
subscribe(sim){ Ticker.subs.add(sim); startTicker(); },
unsubscribe(sim){ Ticker.subs.delete(sim); if (Ticker.subs.size === 0) stopTicker(); },
/* Создаёт IntersectionObserver, который ставит/снимает sim.paused */
observe(sim){
if (!sim.el || !window.IntersectionObserver) return;
const io = new IntersectionObserver(entries => {
entries.forEach(e => { sim.paused = !e.isIntersecting; });
}, { threshold: 0.05 });
io.observe(sim.el);
sim._io = io;
},
/* Безопасное удаление симуляции */
destroy(sim){
util.unsubscribe(sim);
if (sim._io) { try { sim._io.disconnect(); } catch(e){} sim._io = null; }
if (sim.el) sim.el.innerHTML = '';
},
/* Хелпер: создать SVG-обёртку с осями для графика */
svgFrame(w, h, opts){
opts = opts || {};
const bg = opts.bg || '#fafafa';
const border = opts.border || '1px solid #e2e8f0';
return '<svg viewBox="0 0 '+w+' '+h+'" preserveAspectRatio="xMidYMid meet" '
+ 'style="width:100%;height:auto;display:block;background:'+bg
+ ';border:'+border+';border-radius:10px">';
},
/* Двухмерные оси t (горизонтально) и y (вертикально). Возвращает функции toX/toY */
axes(W, H, pad, tMax, yRange){
const left = pad, right = W - pad, top = pad, bot = H - pad;
const ux = (right - left) / tMax;
const uy = (bot - top) / (yRange[1] - yRange[0]);
function toX(t){ return left + t * ux; }
function toY(y){ return bot - (y - yRange[0]) * uy; }
/* SVG сетки + рамки */
let svg = '<g stroke="#e2e8f0" stroke-width="0.8">';
/* Вертикальные линии каждую секунду */
for (let s = 0; s <= tMax; s++) svg += '<line x1="'+toX(s)+'" y1="'+top+'" x2="'+toX(s)+'" y2="'+bot+'"/>';
/* Горизонтальные линии */
const yStep = (yRange[1] - yRange[0]) / 4;
for (let i = 0; i <= 4; i++){
const y = yRange[0] + i * yStep;
svg += '<line x1="'+left+'" y1="'+toY(y)+'" x2="'+right+'" y2="'+toY(y)+'"/>';
}
svg += '</g>';
/* Ось t */
svg += '<line x1="'+left+'" y1="'+toY(0)+'" x2="'+right+'" y2="'+toY(0)+'" stroke="#0f172a" stroke-width="1.4"/>';
/* Ось y */
svg += '<line x1="'+toX(0)+'" y1="'+top+'" x2="'+toX(0)+'" y2="'+bot+'" stroke="#0f172a" stroke-width="1.4"/>';
return { svg: svg, toX, toY, left, right, top, bot };
},
/* Создать ползунок-control под симуляцией.
opts: { label, min, max, step, value, onChange } */
slider(opts){
const id = 'sl-' + Math.random().toString(36).slice(2,7);
const html = '<label style="display:flex;align-items:center;gap:8px;font-size:.82rem;color:#475569;font-weight:600;margin:4px 8px">'
+ '<span style="min-width:90px">' + opts.label + '</span>'
+ '<input type="range" id="' + id + '" min="' + opts.min + '" max="' + opts.max + '" step="' + opts.step + '" value="' + opts.value + '" style="flex:1;min-width:80px">'
+ '<b id="' + id + '-v" style="font-family:JetBrains Mono,monospace;color:#0891b2;font-size:.86rem;min-width:50px;text-align:right">' + opts.value + (opts.unit || '') + '</b>'
+ '</label>';
return { html, id, wire(root){
const inp = root.querySelector('#' + id);
const v = root.querySelector('#' + id + '-v');
if (!inp || !v) return;
inp.addEventListener('input', () => {
const val = parseFloat(inp.value);
v.textContent = (opts.fmt ? opts.fmt(val) : val) + (opts.unit || '');
if (opts.onChange) opts.onChange(val);
});
} };
}
};
/* ============================================================ */
/* Oscillogram — гармонические колебания */
/* ============================================================ */
class Oscillogram {
constructor(container, opts){
opts = opts || {};
this.el = (typeof container === 'string') ? document.querySelector(container) : container;
this.W = opts.width || 560;
this.H = opts.height || 200;
this.pad = opts.pad || 32;
this.tWindow = opts.tWindow || 4; // секунд видно
this.A = opts.A !== undefined ? opts.A : 1.0;
this.omega = opts.omega !== undefined ? opts.omega : 2 * Math.PI;
this.phi0 = opts.phi0 !== undefined ? opts.phi0 : 0;
this.damping = opts.damping || 0;
this.color = opts.color || '#dc2626';
this.label = opts.label || 'x(t)';
this.paused = false;
this.t = 0;
this.history = []; // [t, y] точки за последние tWindow секунд
this._render();
util.subscribe(this);
util.observe(this);
}
setA(v){ this.A = v; }
setOmega(v){ this.omega = v; }
setPhi(v){ this.phi0 = v; }
setDamping(v){ this.damping = v; }
reset(){ this.history = []; this.t = 0; }
update(dt){
this.t += dt;
const y = this.A * Math.exp(-this.damping * this.t) * Math.cos(this.omega * this.t + this.phi0);
this.history.push([this.t, y]);
while (this.history.length && this.history[0][0] < this.t - this.tWindow) this.history.shift();
}
render(){
if (!this.el) return;
const W = this.W, H = this.H, pad = this.pad;
const tMin = Math.max(0, this.t - this.tWindow);
const yRange = [-Math.max(1.05, this.A * 1.1), Math.max(1.05, this.A * 1.1)];
const ax = util.axes(W, H, pad, this.tWindow, yRange);
let polyline = '';
if (this.history.length > 1){
const pts = this.history.map(([t, y]) => (ax.left + (t - tMin) * (ax.right - ax.left) / this.tWindow).toFixed(1) + ',' + ax.toY(y).toFixed(1));
polyline = '<polyline points="' + pts.join(' ') + '" fill="none" stroke="' + this.color + '" stroke-width="2.4" stroke-linejoin="round"/>';
}
/* Подпись y(t) */
const titleSvg = '<text x="' + (W - pad) + '" y="' + (pad - 8) + '" text-anchor="end" font-size="12" font-family="JetBrains Mono,monospace" fill="' + this.color + '" font-weight="700">' + this.label + '</text>';
const svg = util.svgFrame(W, H) + ax.svg + polyline + titleSvg + '</svg>';
this.el.innerHTML = svg;
}
_render(){ this.render(); }
}
P.Oscillogram = Oscillogram;
/* ============================================================ */
/* SpringMass — пружинный маятник (вертикальный) */
/* ============================================================ */
class SpringMass {
constructor(container, opts){
opts = opts || {};
this.el = (typeof container === 'string') ? document.querySelector(container) : container;
this.W = opts.width || 240;
this.H = opts.height || 280;
this.m = opts.m !== undefined ? opts.m : 0.5; // кг
this.k = opts.k !== undefined ? opts.k : 20; // Н
this.A = opts.A !== undefined ? opts.A : 0.06; // м (амплитуда)
this.color = opts.color || '#0891b2';
this.paused = false;
this.t = 0;
this._render();
util.subscribe(this);
util.observe(this);
}
setMass(m){ this.m = Math.max(0.05, m); }
setStiffness(k){ this.k = Math.max(1, k); }
setAmplitude(A){ this.A = Math.max(0.005, A); }
period(){ return 2 * Math.PI * Math.sqrt(this.m / this.k); }
freq(){ return 1 / this.period(); }
update(dt){ this.t += dt; }
render(){
if (!this.el) return;
const W = this.W, H = this.H;
const T = this.period();
const omega = 2 * Math.PI / T;
const A_px = 60; /* визуальная амплитуда в px */
const y0 = 90; /* y-координата равновесия груза в px */
const yCur = y0 + A_px * Math.cos(omega * this.t);
/* Пружина: гармошка-зигзаг от крюка (y=20) до груза (y=yCur-18) */
const cx = W / 2, hookY = 20, massY = yCur, massR = 22;
const coils = 10;
const springTop = hookY;
const springBot = massY - massR;
const segH = (springBot - springTop) / (coils * 2);
let path = 'M ' + cx + ' ' + springTop;
for (let i = 0; i < coils; i++){
path += ' L ' + (cx - 14) + ' ' + (springTop + segH * (2 * i + 1));
path += ' L ' + (cx + 14) + ' ' + (springTop + segH * (2 * i + 2));
}
path += ' L ' + cx + ' ' + springBot;
/* Линейка справа */
const ruler = '<g stroke="#cbd5e1" stroke-width="1" font-family="JetBrains Mono,monospace" font-size="10" fill="#64748b">'
+ '<line x1="' + (W - 38) + '" y1="' + (y0 - A_px) + '" x2="' + (W - 38) + '" y2="' + (y0 + A_px) + '" stroke-width="1.6"/>'
+ '<line x1="' + (W - 44) + '" y1="' + (y0 - A_px) + '" x2="' + (W - 32) + '" y2="' + (y0 - A_px) + '"/>'
+ '<text x="' + (W - 26) + '" y="' + (y0 - A_px + 4) + '">+A</text>'
+ '<line x1="' + (W - 44) + '" y1="' + y0 + '" x2="' + (W - 32) + '" y2="' + y0 + '" stroke="#0f172a" stroke-width="1.4"/>'
+ '<text x="' + (W - 26) + '" y="' + (y0 + 4) + '">0</text>'
+ '<line x1="' + (W - 44) + '" y1="' + (y0 + A_px) + '" x2="' + (W - 32) + '" y2="' + (y0 + A_px) + '"/>'
+ '<text x="' + (W - 26) + '" y="' + (y0 + A_px + 4) + '">-A</text>'
+ '</g>';
/* Период справа сверху */
const Tlabel = '<text x="12" y="20" font-family="JetBrains Mono,monospace" font-size="12" fill="' + this.color + '" font-weight="700">T = ' + T.toFixed(2) + ' с</text>';
const svg = util.svgFrame(W, H, {bg:'#f8fafc'})
+ '<line x1="0" y1="' + (hookY - 6) + '" x2="' + W + '" y2="' + (hookY - 6) + '" stroke="#334155" stroke-width="3"/>'
+ '<g stroke="#334155" stroke-width="3" fill="none" stroke-linejoin="round" stroke-linecap="round">'
+ '<path d="' + path + '"/>'
+ '</g>'
+ '<rect x="' + (cx - massR) + '" y="' + (massY - massR) + '" width="' + (2 * massR) + '" height="' + (2 * massR) + '" rx="6" fill="' + this.color + '" stroke="#0f172a" stroke-width="1.6"/>'
+ '<text x="' + cx + '" y="' + (massY + 5) + '" text-anchor="middle" font-family="Outfit,sans-serif" font-size="14" font-weight="800" fill="#fff">m</text>'
+ ruler + Tlabel
+ '</svg>';
this.el.innerHTML = svg;
}
_render(){ this.render(); }
}
P.SpringMass = SpringMass;
/* ============================================================ */
/* Pendulum — математический маятник */
/* ============================================================ */
class Pendulum {
constructor(container, opts){
opts = opts || {};
this.el = (typeof container === 'string') ? document.querySelector(container) : container;
this.W = opts.width || 240;
this.H = opts.height || 260;
this.l = opts.l !== undefined ? opts.l : 1.0; // м
this.g = opts.g !== undefined ? opts.g : 9.81;
this.theta0 = opts.theta0 !== undefined ? opts.theta0 : Math.PI / 12; // начальный угол (рад)
this.color = opts.color || '#0891b2';
this.paused = false;
this.t = 0;
this._render();
util.subscribe(this);
util.observe(this);
}
setLength(l){ this.l = Math.max(0.1, l); }
setG(g){ this.g = Math.max(0.5, g); }
setTheta0(theta){ this.theta0 = Math.max(0.02, Math.min(Math.PI/4, theta)); }
period(){ return 2 * Math.PI * Math.sqrt(this.l / this.g); }
update(dt){ this.t += dt; }
render(){
if (!this.el) return;
const W = this.W, H = this.H;
const T = this.period();
const omega = 2 * Math.PI / T;
const theta = this.theta0 * Math.cos(omega * this.t);
const cx = W / 2, hookY = 20;
const Lpx = Math.min(160, H - 70);
const bobR = 18;
const bx = cx + Lpx * Math.sin(theta);
const by = hookY + Lpx * Math.cos(theta);
/* Дуга-траектория */
const arcR = Lpx;
const arcStart = -this.theta0;
const arcEnd = this.theta0;
const aS = { x: cx + arcR * Math.sin(arcStart), y: hookY + arcR * Math.cos(arcStart) };
const aE = { x: cx + arcR * Math.sin(arcEnd), y: hookY + arcR * Math.cos(arcEnd) };
const largeArc = (arcEnd - arcStart) > Math.PI ? 1 : 0;
const sweep = 1;
const arc = '<path d="M ' + aS.x.toFixed(1) + ' ' + aS.y.toFixed(1) + ' A ' + arcR + ' ' + arcR + ' 0 ' + largeArc + ' ' + sweep + ' ' + aE.x.toFixed(1) + ' ' + aE.y.toFixed(1) + '" fill="none" stroke="#cbd5e1" stroke-width="1.4" stroke-dasharray="4 4"/>';
/* Вертикальная пунктирная ось */
const vert = '<line x1="' + cx + '" y1="' + hookY + '" x2="' + cx + '" y2="' + (hookY + Lpx + 5) + '" stroke="#cbd5e1" stroke-width="1" stroke-dasharray="3 3"/>';
/* Подвес */
const string = '<line x1="' + cx + '" y1="' + hookY + '" x2="' + bx.toFixed(1) + '" y2="' + by.toFixed(1) + '" stroke="#0f172a" stroke-width="2"/>';
const bob = '<circle cx="' + bx.toFixed(1) + '" cy="' + by.toFixed(1) + '" r="' + bobR + '" fill="' + this.color + '" stroke="#0f172a" stroke-width="1.6"/>';
/* Период */
const Tlabel = '<text x="12" y="20" font-family="JetBrains Mono,monospace" font-size="12" fill="' + this.color + '" font-weight="700">T = ' + T.toFixed(2) + ' с</text>';
/* Подвес-крепление */
const hook = '<line x1="' + (cx - 30) + '" y1="' + (hookY - 6) + '" x2="' + (cx + 30) + '" y2="' + (hookY - 6) + '" stroke="#334155" stroke-width="3"/>';
const svg = util.svgFrame(W, H, {bg:'#f8fafc'}) + hook + vert + arc + string + bob + Tlabel + '</svg>';
this.el.innerHTML = svg;
}
_render(){ this.render(); }
}
P.Pendulum = Pendulum;
})();
+179
View File
@@ -0,0 +1,179 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Физика 11 · Глава 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@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"
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false})"></script>
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<script src="/js/phys-fx.js?v=1" defer></script>
<style>
:root{
--bg:#f8fafc; --card:#fff;
--text:#0f172a; --muted:#475569;
--border:#e2e8f0;
--pri:#0891b2; --pri-d:#0e7490;
--pri-soft:#cffafe;
--dark:#155e75;
--sh:0 4px 16px rgba(0,0,0,.06);
}
html.dark{
--bg:#020617; --card:#0a1929;
--text:#dbeafe; --muted:#94a3b8;
--border:#1e293b;
}
*{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}
.hdr{position:relative;background:linear-gradient(110deg,#155e75 0%,#0891b2 55%,#a5f3fc 100%);color:#fff;padding:32px 24px 28px;overflow:hidden}
.hdr::before{content:'∿';position:absolute;right:8px;top:-20%;font-family:'Outfit',sans-serif;font-size:clamp(8rem,22vw,18rem);font-weight:900;color:rgba(255,255,255,.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.7rem;font-weight:900;letter-spacing:-.01em}
.hdr-sub{font-size:.92rem;opacity:.85;margin-top:4px}
.ic{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
main{max-width:980px;margin:0 auto;padding:32px 24px 60px}
.intro-card{background:var(--card);border:1.5px solid var(--border);border-radius:16px;padding:22px 26px;margin-bottom:28px;box-shadow:var(--sh)}
.intro-num{display:inline-block;padding:4px 10px;background:var(--pri-soft);color:var(--pri-d);border-radius:99px;font-size:.72rem;font-weight:800;letter-spacing:.06em;margin-bottom:8px;text-transform:uppercase}
.intro-card h2{font-family:'Outfit',sans-serif;font-size:1.4rem;font-weight:800;margin-bottom:6px}
.intro-card p{color:var(--muted);font-size:.95rem}
.para-grid{display:grid;grid-template-columns:1fr;gap:14px}
.para-card{background:var(--card);border:1.5px solid var(--border);border-radius:14px;padding:18px 20px;display:flex;gap:16px;align-items:flex-start;transition:transform .15s,box-shadow .15s,border-color .15s}
.para-card:hover{transform:translateY(-2px);box-shadow:var(--sh);border-color:var(--pri)}
.para-num{font-family:'Outfit',sans-serif;font-size:1rem;font-weight:900;color:#fff;background:linear-gradient(135deg,var(--pri),var(--pri-d));padding:8px 12px;border-radius:9px;min-width:56px;text-align:center;letter-spacing:-.02em;flex-shrink:0}
.para-body{flex:1}
.para-title{font-family:'Outfit',sans-serif;font-size:1.05rem;font-weight:800;margin-bottom:4px;color:var(--text)}
.para-sub{font-size:.88rem;color:var(--muted);margin-bottom:10px;line-height:1.55}
.para-status{display:inline-flex;align-items:center;gap:6px;font-size:.78rem;color:var(--muted);background:rgba(0,0,0,.04);padding:6px 10px;border-radius:8px;font-weight:600}
html.dark .para-status{background:rgba(255,255,255,.06)}
.para-status .ic{width:14px;height:14px}
.banner-soon{margin-top:30px;text-align:center;padding:20px;background:linear-gradient(135deg,var(--pri-soft),transparent);border:1px dashed var(--pri);border-radius:14px;color:var(--pri-d);font-weight:700;font-size:.92rem}
.banner-soon b{font-family:'Outfit',sans-serif}
.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="/textbook/physics-11" class="hdr-back">
<svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
К курсу физики 11
</a>
</div>
<div>
<h1>Глава 1. Механические колебания и волны</h1>
<div class="hdr-sub">Колебательное движение, гармонические колебания, маятники, превращения энергии, резонанс, продольные и поперечные волны, звук · §1–§6</div>
</div>
</div>
</header>
<main>
<div class="intro-card">
<span class="intro-num">Глава 1</span>
<h2>Механические колебания и волны</h2>
<p>Колебательное движение, гармонические колебания, маятники, превращения энергии, резонанс, продольные и поперечные волны, звук. Глава содержит 6 параграфов и финальный этап с боссами.</p>
</div>
<div class="para-grid">
<article class="para-card">
<div class="para-num">§ 1</div>
<div class="para-body">
<h2 class="para-title">Колебательное движение. Гармонические колебания</h2>
<p class="para-sub">$T = \Delta t / N$, $\nu = 1/T$, $\omega = 2\pi/T$, $x = A\cos(\omega t + \varphi_0)$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W1-W2
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 2</div>
<div class="para-body">
<h2 class="para-title">Пружинный и математический маятники</h2>
<p class="para-sub">$T_{пр} = 2\pi\sqrt{m/k}$, $T_{мат} = 2\pi\sqrt{l/g}$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W1-W2
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 3</div>
<div class="para-body">
<h2 class="para-title">Превращения энергии при гарм. колебаниях</h2>
<p class="para-sub">$W_{мех} = kA^2/2 = m\omega^2 A^2/2$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W1-W2
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 4</div>
<div class="para-body">
<h2 class="para-title">Свободные и вынужденные колебания. Резонанс</h2>
<p class="para-sub">Затухание, диссипация, $\omega_{рез} \approx \omega_0$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W1-W2
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 5</div>
<div class="para-body">
<h2 class="para-title">Распространение колебаний в упругой среде. Продольные и поперечные волны</h2>
<p class="para-sub">$\lambda = vT$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W1-W2
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 6</div>
<div class="para-body">
<h2 class="para-title">Звуковые волны</h2>
<p class="para-sub">16 Гц 20 кГц, $v_{зв}^{возд} \approx 340$ м/с</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W1-W2
</div>
</div>
</article>
</div>
<div class="banner-soon">
<b>Глава в разработке.</b> Полная реализация — в следующих волнах. Базовая библиотека <code>phys-fx.js</code> уже доступна.
</div>
</main>
<footer class="foot">
Физика — 11 класс · Глава 1 · LearnSpace
</footer>
</body>
</html>
+191
View File
@@ -0,0 +1,191 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Физика 11 · Глава 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@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"
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false})"></script>
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<script src="/js/phys-fx.js?v=1" defer></script>
<style>
:root{
--bg:#f8fafc; --card:#fff;
--text:#0f172a; --muted:#475569;
--border:#e2e8f0;
--pri:#7c3aed; --pri-d:#5b21b6;
--pri-soft:#ede9fe;
--dark:#5b21b6;
--sh:0 4px 16px rgba(0,0,0,.06);
}
html.dark{
--bg:#020617; --card:#0a1929;
--text:#dbeafe; --muted:#94a3b8;
--border:#1e293b;
}
*{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}
.hdr{position:relative;background:linear-gradient(110deg,#5b21b6 0%,#7c3aed 55%,#c4b5fd 100%);color:#fff;padding:32px 24px 28px;overflow:hidden}
.hdr::before{content:'⚡';position:absolute;right:8px;top:-20%;font-family:'Outfit',sans-serif;font-size:clamp(8rem,22vw,18rem);font-weight:900;color:rgba(255,255,255,.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.7rem;font-weight:900;letter-spacing:-.01em}
.hdr-sub{font-size:.92rem;opacity:.85;margin-top:4px}
.ic{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
main{max-width:980px;margin:0 auto;padding:32px 24px 60px}
.intro-card{background:var(--card);border:1.5px solid var(--border);border-radius:16px;padding:22px 26px;margin-bottom:28px;box-shadow:var(--sh)}
.intro-num{display:inline-block;padding:4px 10px;background:var(--pri-soft);color:var(--pri-d);border-radius:99px;font-size:.72rem;font-weight:800;letter-spacing:.06em;margin-bottom:8px;text-transform:uppercase}
.intro-card h2{font-family:'Outfit',sans-serif;font-size:1.4rem;font-weight:800;margin-bottom:6px}
.intro-card p{color:var(--muted);font-size:.95rem}
.para-grid{display:grid;grid-template-columns:1fr;gap:14px}
.para-card{background:var(--card);border:1.5px solid var(--border);border-radius:14px;padding:18px 20px;display:flex;gap:16px;align-items:flex-start;transition:transform .15s,box-shadow .15s,border-color .15s}
.para-card:hover{transform:translateY(-2px);box-shadow:var(--sh);border-color:var(--pri)}
.para-num{font-family:'Outfit',sans-serif;font-size:1rem;font-weight:900;color:#fff;background:linear-gradient(135deg,var(--pri),var(--pri-d));padding:8px 12px;border-radius:9px;min-width:56px;text-align:center;letter-spacing:-.02em;flex-shrink:0}
.para-body{flex:1}
.para-title{font-family:'Outfit',sans-serif;font-size:1.05rem;font-weight:800;margin-bottom:4px;color:var(--text)}
.para-sub{font-size:.88rem;color:var(--muted);margin-bottom:10px;line-height:1.55}
.para-status{display:inline-flex;align-items:center;gap:6px;font-size:.78rem;color:var(--muted);background:rgba(0,0,0,.04);padding:6px 10px;border-radius:8px;font-weight:600}
html.dark .para-status{background:rgba(255,255,255,.06)}
.para-status .ic{width:14px;height:14px}
.banner-soon{margin-top:30px;text-align:center;padding:20px;background:linear-gradient(135deg,var(--pri-soft),transparent);border:1px dashed var(--pri);border-radius:14px;color:var(--pri-d);font-weight:700;font-size:.92rem}
.banner-soon b{font-family:'Outfit',sans-serif}
.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="/textbook/physics-11" class="hdr-back">
<svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
К курсу физики 11
</a>
</div>
<div>
<h1>Глава 2. Электромагнитные колебания и волны</h1>
<div class="hdr-sub">Колебательный контур, формула Томсона, переменный ток, трансформатор, передача электроэнергии, ЭМ волны · §7–§13</div>
</div>
</div>
</header>
<main>
<div class="intro-card">
<span class="intro-num">Глава 2</span>
<h2>Электромагнитные колебания и волны</h2>
<p>Колебательный контур, формула Томсона, переменный ток, трансформатор, передача электроэнергии, ЭМ волны. Глава содержит 7 параграфов и финальный этап с боссами.</p>
</div>
<div class="para-grid">
<article class="para-card">
<div class="para-num">§ 7</div>
<div class="para-body">
<h2 class="para-title">Колебательный контур. Свободные ЭМ колебания. Формула Томсона</h2>
<p class="para-sub">$T = 2\pi\sqrt{LC}$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W3-W4
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 8</div>
<div class="para-body">
<h2 class="para-title">Вынужденные ЭМ колебания. Переменный ток</h2>
<p class="para-sub">$i = I_0\sin(\omega t)$, $I = I_0/\sqrt{2}$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W3-W4
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 9</div>
<div class="para-body">
<h2 class="para-title">Преобразование переменного тока. Трансформатор</h2>
<p class="para-sub">$k = N_1/N_2 = U_1/U_2$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W3-W4
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 10</div>
<div class="para-body">
<h2 class="para-title">Производство, передача и потребление электроэнергии</h2>
<p class="para-sub">ГЭС, ТЭС, АЭС; потери $P = I^2 R$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W3-W4
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 11</div>
<div class="para-body">
<h2 class="para-title">Экологические проблемы производства и передачи электроэнергии</h2>
<p class="para-sub">ВЭС, СЭС, гео- и приливные</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W3-W4
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 12</div>
<div class="para-body">
<h2 class="para-title">ЭМ волны. Шкала ЭМ волн</h2>
<p class="para-sub">$c = 3 \cdot 10^8$ м/с</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W3-W4
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 13</div>
<div class="para-body">
<h2 class="para-title">Действие ЭМ излучения на живые организмы</h2>
<p class="para-sub">Ионизирующее vs неионизирующее</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W3-W4
</div>
</div>
</article>
</div>
<div class="banner-soon">
<b>Глава в разработке.</b> Полная реализация — в следующих волнах. Базовая библиотека <code>phys-fx.js</code> уже доступна.
</div>
</main>
<footer class="foot">
Физика — 11 класс · Глава 2 · LearnSpace
</footer>
</body>
</html>
+227
View File
@@ -0,0 +1,227 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Физика 11 · Глава 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@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"
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false})"></script>
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<script src="/js/phys-fx.js?v=1" defer></script>
<style>
:root{
--bg:#f8fafc; --card:#fff;
--text:#0f172a; --muted:#475569;
--border:#e2e8f0;
--pri:#d97706; --pri-d:#b45309;
--pri-soft:#fef3c7;
--dark:#b45309;
--sh:0 4px 16px rgba(0,0,0,.06);
}
html.dark{
--bg:#020617; --card:#0a1929;
--text:#dbeafe; --muted:#94a3b8;
--border:#1e293b;
}
*{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}
.hdr{position:relative;background:linear-gradient(110deg,#b45309 0%,#d97706 55%,#fcd34d 100%);color:#fff;padding:32px 24px 28px;overflow:hidden}
.hdr::before{content:'◇';position:absolute;right:8px;top:-20%;font-family:'Outfit',sans-serif;font-size:clamp(8rem,22vw,18rem);font-weight:900;color:rgba(255,255,255,.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.7rem;font-weight:900;letter-spacing:-.01em}
.hdr-sub{font-size:.92rem;opacity:.85;margin-top:4px}
.ic{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
main{max-width:980px;margin:0 auto;padding:32px 24px 60px}
.intro-card{background:var(--card);border:1.5px solid var(--border);border-radius:16px;padding:22px 26px;margin-bottom:28px;box-shadow:var(--sh)}
.intro-num{display:inline-block;padding:4px 10px;background:var(--pri-soft);color:var(--pri-d);border-radius:99px;font-size:.72rem;font-weight:800;letter-spacing:.06em;margin-bottom:8px;text-transform:uppercase}
.intro-card h2{font-family:'Outfit',sans-serif;font-size:1.4rem;font-weight:800;margin-bottom:6px}
.intro-card p{color:var(--muted);font-size:.95rem}
.para-grid{display:grid;grid-template-columns:1fr;gap:14px}
.para-card{background:var(--card);border:1.5px solid var(--border);border-radius:14px;padding:18px 20px;display:flex;gap:16px;align-items:flex-start;transition:transform .15s,box-shadow .15s,border-color .15s}
.para-card:hover{transform:translateY(-2px);box-shadow:var(--sh);border-color:var(--pri)}
.para-num{font-family:'Outfit',sans-serif;font-size:1rem;font-weight:900;color:#fff;background:linear-gradient(135deg,var(--pri),var(--pri-d));padding:8px 12px;border-radius:9px;min-width:56px;text-align:center;letter-spacing:-.02em;flex-shrink:0}
.para-body{flex:1}
.para-title{font-family:'Outfit',sans-serif;font-size:1.05rem;font-weight:800;margin-bottom:4px;color:var(--text)}
.para-sub{font-size:.88rem;color:var(--muted);margin-bottom:10px;line-height:1.55}
.para-status{display:inline-flex;align-items:center;gap:6px;font-size:.78rem;color:var(--muted);background:rgba(0,0,0,.04);padding:6px 10px;border-radius:8px;font-weight:600}
html.dark .para-status{background:rgba(255,255,255,.06)}
.para-status .ic{width:14px;height:14px}
.banner-soon{margin-top:30px;text-align:center;padding:20px;background:linear-gradient(135deg,var(--pri-soft),transparent);border:1px dashed var(--pri);border-radius:14px;color:var(--pri-d);font-weight:700;font-size:.92rem}
.banner-soon b{font-family:'Outfit',sans-serif}
.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="/textbook/physics-11" class="hdr-back">
<svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
К курсу физики 11
</a>
</div>
<div>
<h1>Глава 3. Оптика</h1>
<div class="hdr-sub">Электромагнитная природа света, интерференция, дифракция, отражение, зеркала, преломление, тонкая линза, оптические приборы · §14–§23</div>
</div>
</div>
</header>
<main>
<div class="intro-card">
<span class="intro-num">Глава 3</span>
<h2>Оптика</h2>
<p>Электромагнитная природа света, интерференция, дифракция, отражение, зеркала, преломление, тонкая линза, оптические приборы. Глава содержит 10 параграфов и финальный этап с боссами.</p>
</div>
<div class="para-grid">
<article class="para-card">
<div class="para-num">§ 14</div>
<div class="para-body">
<h2 class="para-title">ЭМ природа света. Скорость света</h2>
<p class="para-sub">Опыты Рёмера, Майкельсона</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W5-W7
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 15</div>
<div class="para-body">
<h2 class="para-title">Интерференция света</h2>
<p class="para-sub">$\Delta = k\lambda$ (max), $\Delta = (2k+1)\lambda/2$ (min)</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W5-W7
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 16</div>
<div class="para-body">
<h2 class="para-title">Принцип Гюйгенса – Френеля. Дифракция. Дифракционная решётка</h2>
<p class="para-sub">$d\sin\varphi = k\lambda$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W5-W7
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 17</div>
<div class="para-body">
<h2 class="para-title">Прямолинейное распространение и отражение света. Зеркала</h2>
<p class="para-sub">$\angle_{пад} = \angle_{отр}$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W5-W7
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 18</div>
<div class="para-body">
<h2 class="para-title">Сферические зеркала. Построение изображений</h2>
<p class="para-sub">$\frac{1}{F} = \frac{1}{d} + \frac{1}{f}$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W5-W7
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 19</div>
<div class="para-body">
<h2 class="para-title">Закон преломления света. Полное отражение</h2>
<p class="para-sub">$n_1\sin\alpha = n_2\sin\beta$, $\sin\alpha_{пр} = 1/n$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W5-W7
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 20</div>
<div class="para-body">
<h2 class="para-title">Прохождение света через оптические элементы</h2>
<p class="para-sub">Призмы, оптоволокно</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W5-W7
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 21</div>
<div class="para-body">
<h2 class="para-title">Формула тонкой линзы</h2>
<p class="para-sub">$D = 1/F$, $\Gamma = f/d$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W5-W7
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 22</div>
<div class="para-body">
<h2 class="para-title">Оптические приборы для действительных изображений</h2>
<p class="para-sub">Фотоаппарат, проектор</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W5-W7
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 23</div>
<div class="para-body">
<h2 class="para-title">Оптические приборы для увеличения угла зрения</h2>
<p class="para-sub">Лупа, микроскоп, телескоп</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W5-W7
</div>
</div>
</article>
</div>
<div class="banner-soon">
<b>Глава в разработке.</b> Полная реализация — в следующих волнах. Базовая библиотека <code>phys-fx.js</code> уже доступна.
</div>
</main>
<footer class="foot">
Физика — 11 класс · Глава 3 · LearnSpace
</footer>
</body>
</html>
+143
View File
@@ -0,0 +1,143 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Физика 11 · Глава 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@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"
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false})"></script>
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<script src="/js/phys-fx.js?v=1" defer></script>
<style>
:root{
--bg:#f8fafc; --card:#fff;
--text:#0f172a; --muted:#475569;
--border:#e2e8f0;
--pri:#2563eb; --pri-d:#1d4ed8;
--pri-soft:#dbeafe;
--dark:#1e3a8a;
--sh:0 4px 16px rgba(0,0,0,.06);
}
html.dark{
--bg:#020617; --card:#0a1929;
--text:#dbeafe; --muted:#94a3b8;
--border:#1e293b;
}
*{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}
.hdr{position:relative;background:linear-gradient(110deg,#1e3a8a 0%,#2563eb 55%,#93c5fd 100%);color:#fff;padding:32px 24px 28px;overflow:hidden}
.hdr::before{content:'c';position:absolute;right:8px;top:-20%;font-family:'Outfit',sans-serif;font-size:clamp(8rem,22vw,18rem);font-weight:900;color:rgba(255,255,255,.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.7rem;font-weight:900;letter-spacing:-.01em}
.hdr-sub{font-size:.92rem;opacity:.85;margin-top:4px}
.ic{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
main{max-width:980px;margin:0 auto;padding:32px 24px 60px}
.intro-card{background:var(--card);border:1.5px solid var(--border);border-radius:16px;padding:22px 26px;margin-bottom:28px;box-shadow:var(--sh)}
.intro-num{display:inline-block;padding:4px 10px;background:var(--pri-soft);color:var(--pri-d);border-radius:99px;font-size:.72rem;font-weight:800;letter-spacing:.06em;margin-bottom:8px;text-transform:uppercase}
.intro-card h2{font-family:'Outfit',sans-serif;font-size:1.4rem;font-weight:800;margin-bottom:6px}
.intro-card p{color:var(--muted);font-size:.95rem}
.para-grid{display:grid;grid-template-columns:1fr;gap:14px}
.para-card{background:var(--card);border:1.5px solid var(--border);border-radius:14px;padding:18px 20px;display:flex;gap:16px;align-items:flex-start;transition:transform .15s,box-shadow .15s,border-color .15s}
.para-card:hover{transform:translateY(-2px);box-shadow:var(--sh);border-color:var(--pri)}
.para-num{font-family:'Outfit',sans-serif;font-size:1rem;font-weight:900;color:#fff;background:linear-gradient(135deg,var(--pri),var(--pri-d));padding:8px 12px;border-radius:9px;min-width:56px;text-align:center;letter-spacing:-.02em;flex-shrink:0}
.para-body{flex:1}
.para-title{font-family:'Outfit',sans-serif;font-size:1.05rem;font-weight:800;margin-bottom:4px;color:var(--text)}
.para-sub{font-size:.88rem;color:var(--muted);margin-bottom:10px;line-height:1.55}
.para-status{display:inline-flex;align-items:center;gap:6px;font-size:.78rem;color:var(--muted);background:rgba(0,0,0,.04);padding:6px 10px;border-radius:8px;font-weight:600}
html.dark .para-status{background:rgba(255,255,255,.06)}
.para-status .ic{width:14px;height:14px}
.banner-soon{margin-top:30px;text-align:center;padding:20px;background:linear-gradient(135deg,var(--pri-soft),transparent);border:1px dashed var(--pri);border-radius:14px;color:var(--pri-d);font-weight:700;font-size:.92rem}
.banner-soon b{font-family:'Outfit',sans-serif}
.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="/textbook/physics-11" class="hdr-back">
<svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
К курсу физики 11
</a>
</div>
<div>
<h1>Глава 4. Основы СТО</h1>
<div class="hdr-sub">Принцип относительности Галилея, постулаты Эйнштейна, преобразования Лоренца, релятивистская динамика, E=mc² · §24–§26</div>
</div>
</div>
</header>
<main>
<div class="intro-card">
<span class="intro-num">Глава 4</span>
<h2>Основы СТО</h2>
<p>Принцип относительности Галилея, постулаты Эйнштейна, преобразования Лоренца, релятивистская динамика, E=mc². Глава содержит 3 параграфа и финальный этап с боссами.</p>
</div>
<div class="para-grid">
<article class="para-card">
<div class="para-num">§ 24</div>
<div class="para-body">
<h2 class="para-title">Принцип относ. Галилея и ЭМ явления. Эксп. предпосылки СТО</h2>
<p class="para-sub">Опыт Майкельсона – Морли</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W8
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 25</div>
<div class="para-body">
<h2 class="para-title">Постулаты специальной теории относительности</h2>
<p class="para-sub">$\Delta t = \gamma\Delta t_0$, $l = l_0/\gamma$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W8
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 26</div>
<div class="para-body">
<h2 class="para-title">Элементы релятивистской динамики. Взаимосвязь массы и энергии</h2>
<p class="para-sub">$E_0 = mc^2$, $E^2 = (mc^2)^2 + (pc)^2$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W8
</div>
</div>
</article>
</div>
<div class="banner-soon">
<b>Глава в разработке.</b> Полная реализация — в следующих волнах. Базовая библиотека <code>phys-fx.js</code> уже доступна.
</div>
</main>
<footer class="foot">
Физика — 11 класс · Глава 4 · LearnSpace
</footer>
</body>
</html>
+143
View File
@@ -0,0 +1,143 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Физика 11 · Глава 5 · Фотоны. Действия света</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"
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false})"></script>
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<script src="/js/phys-fx.js?v=1" defer></script>
<style>
:root{
--bg:#f8fafc; --card:#fff;
--text:#0f172a; --muted:#475569;
--border:#e2e8f0;
--pri:#db2777; --pri-d:#9d174d;
--pri-soft:#fce7f3;
--dark:#831843;
--sh:0 4px 16px rgba(0,0,0,.06);
}
html.dark{
--bg:#020617; --card:#0a1929;
--text:#dbeafe; --muted:#94a3b8;
--border:#1e293b;
}
*{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}
.hdr{position:relative;background:linear-gradient(110deg,#831843 0%,#db2777 55%,#fbcfe8 100%);color:#fff;padding:32px 24px 28px;overflow:hidden}
.hdr::before{content:'γ';position:absolute;right:8px;top:-20%;font-family:'Outfit',sans-serif;font-size:clamp(8rem,22vw,18rem);font-weight:900;color:rgba(255,255,255,.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.7rem;font-weight:900;letter-spacing:-.01em}
.hdr-sub{font-size:.92rem;opacity:.85;margin-top:4px}
.ic{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
main{max-width:980px;margin:0 auto;padding:32px 24px 60px}
.intro-card{background:var(--card);border:1.5px solid var(--border);border-radius:16px;padding:22px 26px;margin-bottom:28px;box-shadow:var(--sh)}
.intro-num{display:inline-block;padding:4px 10px;background:var(--pri-soft);color:var(--pri-d);border-radius:99px;font-size:.72rem;font-weight:800;letter-spacing:.06em;margin-bottom:8px;text-transform:uppercase}
.intro-card h2{font-family:'Outfit',sans-serif;font-size:1.4rem;font-weight:800;margin-bottom:6px}
.intro-card p{color:var(--muted);font-size:.95rem}
.para-grid{display:grid;grid-template-columns:1fr;gap:14px}
.para-card{background:var(--card);border:1.5px solid var(--border);border-radius:14px;padding:18px 20px;display:flex;gap:16px;align-items:flex-start;transition:transform .15s,box-shadow .15s,border-color .15s}
.para-card:hover{transform:translateY(-2px);box-shadow:var(--sh);border-color:var(--pri)}
.para-num{font-family:'Outfit',sans-serif;font-size:1rem;font-weight:900;color:#fff;background:linear-gradient(135deg,var(--pri),var(--pri-d));padding:8px 12px;border-radius:9px;min-width:56px;text-align:center;letter-spacing:-.02em;flex-shrink:0}
.para-body{flex:1}
.para-title{font-family:'Outfit',sans-serif;font-size:1.05rem;font-weight:800;margin-bottom:4px;color:var(--text)}
.para-sub{font-size:.88rem;color:var(--muted);margin-bottom:10px;line-height:1.55}
.para-status{display:inline-flex;align-items:center;gap:6px;font-size:.78rem;color:var(--muted);background:rgba(0,0,0,.04);padding:6px 10px;border-radius:8px;font-weight:600}
html.dark .para-status{background:rgba(255,255,255,.06)}
.para-status .ic{width:14px;height:14px}
.banner-soon{margin-top:30px;text-align:center;padding:20px;background:linear-gradient(135deg,var(--pri-soft),transparent);border:1px dashed var(--pri);border-radius:14px;color:var(--pri-d);font-weight:700;font-size:.92rem}
.banner-soon b{font-family:'Outfit',sans-serif}
.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="/textbook/physics-11" class="hdr-back">
<svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
К курсу физики 11
</a>
</div>
<div>
<h1>Глава 5. Фотоны. Действия света</h1>
<div class="hdr-sub">Фотоэффект, квантовая гипотеза Планка, фотон, уравнение Эйнштейна, давление света, корпускулярно-волновой дуализм · §27–§29</div>
</div>
</div>
</header>
<main>
<div class="intro-card">
<span class="intro-num">Глава 5</span>
<h2>Фотоны. Действия света</h2>
<p>Фотоэффект, квантовая гипотеза Планка, фотон, уравнение Эйнштейна, давление света, корпускулярно-волновой дуализм. Глава содержит 3 параграфа и финальный этап с боссами.</p>
</div>
<div class="para-grid">
<article class="para-card">
<div class="para-num">§ 27</div>
<div class="para-body">
<h2 class="para-title">Фотоэффект. Эксперим. законы. Квантовая гипотеза Планка</h2>
<p class="para-sub">$E = h\nu$, $h = 6{,}63 \cdot 10^{-34}$ Дж·с</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W9
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 28</div>
<div class="para-body">
<h2 class="para-title">Фотон. Уравнение Эйнштейна для фотоэффекта</h2>
<p class="para-sub">$h\nu = A_{вых} + \frac{mv_{max}^2}{2}$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W9
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 29</div>
<div class="para-body">
<h2 class="para-title">Давление света. Корпускулярно-волновой дуализм</h2>
<p class="para-sub">$p_{фот} = h\nu/c$. Опыт Лебедева</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W9
</div>
</div>
</article>
</div>
<div class="banner-soon">
<b>Глава в разработке.</b> Полная реализация — в следующих волнах. Базовая библиотека <code>phys-fx.js</code> уже доступна.
</div>
</main>
<footer class="foot">
Физика — 11 класс · Глава 5 · LearnSpace
</footer>
</body>
</html>
+167
View File
@@ -0,0 +1,167 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Физика 11 · Глава 6 · Физика атома</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"
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false})"></script>
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<script src="/js/phys-fx.js?v=1" defer></script>
<style>
:root{
--bg:#f8fafc; --card:#fff;
--text:#0f172a; --muted:#475569;
--border:#e2e8f0;
--pri:#10b981; --pri-d:#047857;
--pri-soft:#d1fae5;
--dark:#065f46;
--sh:0 4px 16px rgba(0,0,0,.06);
}
html.dark{
--bg:#020617; --card:#0a1929;
--text:#dbeafe; --muted:#94a3b8;
--border:#1e293b;
}
*{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}
.hdr{position:relative;background:linear-gradient(110deg,#065f46 0%,#10b981 55%,#a7f3d0 100%);color:#fff;padding:32px 24px 28px;overflow:hidden}
.hdr::before{content:'⚛';position:absolute;right:8px;top:-20%;font-family:'Outfit',sans-serif;font-size:clamp(8rem,22vw,18rem);font-weight:900;color:rgba(255,255,255,.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.7rem;font-weight:900;letter-spacing:-.01em}
.hdr-sub{font-size:.92rem;opacity:.85;margin-top:4px}
.ic{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
main{max-width:980px;margin:0 auto;padding:32px 24px 60px}
.intro-card{background:var(--card);border:1.5px solid var(--border);border-radius:16px;padding:22px 26px;margin-bottom:28px;box-shadow:var(--sh)}
.intro-num{display:inline-block;padding:4px 10px;background:var(--pri-soft);color:var(--pri-d);border-radius:99px;font-size:.72rem;font-weight:800;letter-spacing:.06em;margin-bottom:8px;text-transform:uppercase}
.intro-card h2{font-family:'Outfit',sans-serif;font-size:1.4rem;font-weight:800;margin-bottom:6px}
.intro-card p{color:var(--muted);font-size:.95rem}
.para-grid{display:grid;grid-template-columns:1fr;gap:14px}
.para-card{background:var(--card);border:1.5px solid var(--border);border-radius:14px;padding:18px 20px;display:flex;gap:16px;align-items:flex-start;transition:transform .15s,box-shadow .15s,border-color .15s}
.para-card:hover{transform:translateY(-2px);box-shadow:var(--sh);border-color:var(--pri)}
.para-num{font-family:'Outfit',sans-serif;font-size:1rem;font-weight:900;color:#fff;background:linear-gradient(135deg,var(--pri),var(--pri-d));padding:8px 12px;border-radius:9px;min-width:56px;text-align:center;letter-spacing:-.02em;flex-shrink:0}
.para-body{flex:1}
.para-title{font-family:'Outfit',sans-serif;font-size:1.05rem;font-weight:800;margin-bottom:4px;color:var(--text)}
.para-sub{font-size:.88rem;color:var(--muted);margin-bottom:10px;line-height:1.55}
.para-status{display:inline-flex;align-items:center;gap:6px;font-size:.78rem;color:var(--muted);background:rgba(0,0,0,.04);padding:6px 10px;border-radius:8px;font-weight:600}
html.dark .para-status{background:rgba(255,255,255,.06)}
.para-status .ic{width:14px;height:14px}
.banner-soon{margin-top:30px;text-align:center;padding:20px;background:linear-gradient(135deg,var(--pri-soft),transparent);border:1px dashed var(--pri);border-radius:14px;color:var(--pri-d);font-weight:700;font-size:.92rem}
.banner-soon b{font-family:'Outfit',sans-serif}
.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="/textbook/physics-11" class="hdr-back">
<svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
К курсу физики 11
</a>
</div>
<div>
<h1>Глава 6. Физика атома</h1>
<div class="hdr-sub">Ядерная модель атома Резерфорда, квантовые постулаты Бора, спектры испускания и поглощения, лазеры · §30–§34</div>
</div>
</div>
</header>
<main>
<div class="intro-card">
<span class="intro-num">Глава 6</span>
<h2>Физика атома</h2>
<p>Ядерная модель атома Резерфорда, квантовые постулаты Бора, спектры испускания и поглощения, лазеры. Глава содержит 5 параграфов и финальный этап с боссами.</p>
</div>
<div class="para-grid">
<article class="para-card">
<div class="para-num">§ 30</div>
<div class="para-body">
<h2 class="para-title">Сложное строение атома. Ядерная модель атома</h2>
<p class="para-sub">Опыт Резерфорда, размер ядра $\sim 10^{-15}$ м</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W10-W11
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 31</div>
<div class="para-body">
<h2 class="para-title">Квантовые постулаты Бора</h2>
<p class="para-sub">$E_n = -E_1/n^2 = -13{,}6/n^2$ эВ</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W10-W11
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 32</div>
<div class="para-body">
<h2 class="para-title">Излучение и поглощение света атомом. Спектры</h2>
<p class="para-sub">$h\nu = E_n - E_m$, линейчатые спектры</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W10-W11
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 33</div>
<div class="para-body">
<h2 class="para-title">Спонтанное и индуцированное излучение</h2>
<p class="para-sub">Подготовка к лазерам</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W10-W11
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 34</div>
<div class="para-body">
<h2 class="para-title">Лазеры</h2>
<p class="para-sub">Инверсная населённость, когерентность</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W10-W11
</div>
</div>
</article>
</div>
<div class="banner-soon">
<b>Глава в разработке.</b> Полная реализация — в следующих волнах. Базовая библиотека <code>phys-fx.js</code> уже доступна.
</div>
</main>
<footer class="foot">
Физика — 11 класс · Глава 6 · LearnSpace
</footer>
</body>
</html>
+227
View File
@@ -0,0 +1,227 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Физика 11 · Глава 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"
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false})"></script>
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<script src="/js/phys-fx.js?v=1" defer></script>
<style>
:root{
--bg:#f8fafc; --card:#fff;
--text:#0f172a; --muted:#475569;
--border:#e2e8f0;
--pri:#dc2626; --pri-d:#991b1b;
--pri-soft:#fee2e2;
--dark:#7f1d1d;
--sh:0 4px 16px rgba(0,0,0,.06);
}
html.dark{
--bg:#020617; --card:#0a1929;
--text:#dbeafe; --muted:#94a3b8;
--border:#1e293b;
}
*{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}
.hdr{position:relative;background:linear-gradient(110deg,#7f1d1d 0%,#dc2626 55%,#fca5a5 100%);color:#fff;padding:32px 24px 28px;overflow:hidden}
.hdr::before{content:'☢';position:absolute;right:8px;top:-20%;font-family:'Outfit',sans-serif;font-size:clamp(8rem,22vw,18rem);font-weight:900;color:rgba(255,255,255,.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.7rem;font-weight:900;letter-spacing:-.01em}
.hdr-sub{font-size:.92rem;opacity:.85;margin-top:4px}
.ic{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
main{max-width:980px;margin:0 auto;padding:32px 24px 60px}
.intro-card{background:var(--card);border:1.5px solid var(--border);border-radius:16px;padding:22px 26px;margin-bottom:28px;box-shadow:var(--sh)}
.intro-num{display:inline-block;padding:4px 10px;background:var(--pri-soft);color:var(--pri-d);border-radius:99px;font-size:.72rem;font-weight:800;letter-spacing:.06em;margin-bottom:8px;text-transform:uppercase}
.intro-card h2{font-family:'Outfit',sans-serif;font-size:1.4rem;font-weight:800;margin-bottom:6px}
.intro-card p{color:var(--muted);font-size:.95rem}
.para-grid{display:grid;grid-template-columns:1fr;gap:14px}
.para-card{background:var(--card);border:1.5px solid var(--border);border-radius:14px;padding:18px 20px;display:flex;gap:16px;align-items:flex-start;transition:transform .15s,box-shadow .15s,border-color .15s}
.para-card:hover{transform:translateY(-2px);box-shadow:var(--sh);border-color:var(--pri)}
.para-num{font-family:'Outfit',sans-serif;font-size:1rem;font-weight:900;color:#fff;background:linear-gradient(135deg,var(--pri),var(--pri-d));padding:8px 12px;border-radius:9px;min-width:56px;text-align:center;letter-spacing:-.02em;flex-shrink:0}
.para-body{flex:1}
.para-title{font-family:'Outfit',sans-serif;font-size:1.05rem;font-weight:800;margin-bottom:4px;color:var(--text)}
.para-sub{font-size:.88rem;color:var(--muted);margin-bottom:10px;line-height:1.55}
.para-status{display:inline-flex;align-items:center;gap:6px;font-size:.78rem;color:var(--muted);background:rgba(0,0,0,.04);padding:6px 10px;border-radius:8px;font-weight:600}
html.dark .para-status{background:rgba(255,255,255,.06)}
.para-status .ic{width:14px;height:14px}
.banner-soon{margin-top:30px;text-align:center;padding:20px;background:linear-gradient(135deg,var(--pri-soft),transparent);border:1px dashed var(--pri);border-radius:14px;color:var(--pri-d);font-weight:700;font-size:.92rem}
.banner-soon b{font-family:'Outfit',sans-serif}
.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="/textbook/physics-11" class="hdr-back">
<svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
К курсу физики 11
</a>
</div>
<div>
<h1>Глава 7. Ядерная физика и элементарные частицы</h1>
<div class="hdr-sub">Протонно-нейтронная модель ядра, ядерные реакции, энергия связи, радиоактивность, ядерный реактор, термояд, элементарные частицы · §35–§44</div>
</div>
</div>
</header>
<main>
<div class="intro-card">
<span class="intro-num">Глава 7</span>
<h2>Ядерная физика и элементарные частицы</h2>
<p>Протонно-нейтронная модель ядра, ядерные реакции, энергия связи, радиоактивность, ядерный реактор, термояд, элементарные частицы. Глава содержит 10 параграфов и финальный этап с боссами.</p>
</div>
<div class="para-grid">
<article class="para-card">
<div class="para-num">§ 35</div>
<div class="para-body">
<h2 class="para-title">Протонно-нейтронная модель строения ядра атома</h2>
<p class="para-sub">$A = Z + N$, изотопы</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W12-W13
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 36</div>
<div class="para-body">
<h2 class="para-title">Ядерные реакции. Законы сохранения в ядерных реакциях</h2>
<p class="para-sub">Сохранение заряда, нуклонов, энергии</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W12-W13
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 37</div>
<div class="para-body">
<h2 class="para-title">Энергия связи ядра атома</h2>
<p class="para-sub">$E_{св} = \Delta m \cdot c^2$, $\Delta m = Zm_p + Nm_n - m_я$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W12-W13
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 38</div>
<div class="para-body">
<h2 class="para-title">Радиоактивность</h2>
<p class="para-sub">$\alpha$, $\beta$, $\gamma$ распады</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W12-W13
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 39</div>
<div class="para-body">
<h2 class="para-title">Закон радиоактивного распада</h2>
<p class="para-sub">$N = N_0 \cdot 2^{-t/T}$, период полураспада $T$</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W12-W13
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 40</div>
<div class="para-body">
<h2 class="para-title">Деление тяжёлых ядер. Цепные ядерные реакции</h2>
<p class="para-sub">$^{235}$U, $k$ — коэф. размножения</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W12-W13
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 41</div>
<div class="para-body">
<h2 class="para-title">Ядерный реактор</h2>
<p class="para-sub">Управляющие стержни, замедлитель</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W12-W13
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 42</div>
<div class="para-body">
<h2 class="para-title">Реакции ядерного синтеза</h2>
<p class="para-sub">Термояд, $^2$H + $^3$H $\to ^4$He + n</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W12-W13
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 43</div>
<div class="para-body">
<h2 class="para-title">Ионизирующее излучение. Элементы дозиметрии</h2>
<p class="para-sub">Доза $D$, эквивалент $H$, зиверт</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W12-W13
</div>
</div>
</article>
<article class="para-card">
<div class="para-num">§ 44</div>
<div class="para-body">
<h2 class="para-title">Элементарные частицы и их взаимодействия</h2>
<p class="para-sub">Стандартная модель, 4 фундаментальных взаимодействия</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W12-W13
</div>
</div>
</article>
</div>
<div class="banner-soon">
<b>Глава в разработке.</b> Полная реализация — в следующих волнах. Базовая библиотека <code>phys-fx.js</code> уже доступна.
</div>
</main>
<footer class="foot">
Физика — 11 класс · Глава 7 · LearnSpace
</footer>
</body>
</html>
+119
View File
@@ -0,0 +1,119 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Физика 11 · Глава 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">
<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"
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false})"></script>
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<script src="/js/phys-fx.js?v=1" defer></script>
<style>
:root{
--bg:#f8fafc; --card:#fff;
--text:#0f172a; --muted:#475569;
--border:#e2e8f0;
--pri:#6366f1; --pri-d:#4338ca;
--pri-soft:#e0e7ff;
--dark:#3730a3;
--sh:0 4px 16px rgba(0,0,0,.06);
}
html.dark{
--bg:#020617; --card:#0a1929;
--text:#dbeafe; --muted:#94a3b8;
--border:#1e293b;
}
*{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}
.hdr{position:relative;background:linear-gradient(110deg,#3730a3 0%,#6366f1 55%,#c7d2fe 100%);color:#fff;padding:32px 24px 28px;overflow:hidden}
.hdr::before{content:'∞';position:absolute;right:8px;top:-20%;font-family:'Outfit',sans-serif;font-size:clamp(8rem,22vw,18rem);font-weight:900;color:rgba(255,255,255,.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.7rem;font-weight:900;letter-spacing:-.01em}
.hdr-sub{font-size:.92rem;opacity:.85;margin-top:4px}
.ic{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
main{max-width:980px;margin:0 auto;padding:32px 24px 60px}
.intro-card{background:var(--card);border:1.5px solid var(--border);border-radius:16px;padding:22px 26px;margin-bottom:28px;box-shadow:var(--sh)}
.intro-num{display:inline-block;padding:4px 10px;background:var(--pri-soft);color:var(--pri-d);border-radius:99px;font-size:.72rem;font-weight:800;letter-spacing:.06em;margin-bottom:8px;text-transform:uppercase}
.intro-card h2{font-family:'Outfit',sans-serif;font-size:1.4rem;font-weight:800;margin-bottom:6px}
.intro-card p{color:var(--muted);font-size:.95rem}
.para-grid{display:grid;grid-template-columns:1fr;gap:14px}
.para-card{background:var(--card);border:1.5px solid var(--border);border-radius:14px;padding:18px 20px;display:flex;gap:16px;align-items:flex-start;transition:transform .15s,box-shadow .15s,border-color .15s}
.para-card:hover{transform:translateY(-2px);box-shadow:var(--sh);border-color:var(--pri)}
.para-num{font-family:'Outfit',sans-serif;font-size:1rem;font-weight:900;color:#fff;background:linear-gradient(135deg,var(--pri),var(--pri-d));padding:8px 12px;border-radius:9px;min-width:56px;text-align:center;letter-spacing:-.02em;flex-shrink:0}
.para-body{flex:1}
.para-title{font-family:'Outfit',sans-serif;font-size:1.05rem;font-weight:800;margin-bottom:4px;color:var(--text)}
.para-sub{font-size:.88rem;color:var(--muted);margin-bottom:10px;line-height:1.55}
.para-status{display:inline-flex;align-items:center;gap:6px;font-size:.78rem;color:var(--muted);background:rgba(0,0,0,.04);padding:6px 10px;border-radius:8px;font-weight:600}
html.dark .para-status{background:rgba(255,255,255,.06)}
.para-status .ic{width:14px;height:14px}
.banner-soon{margin-top:30px;text-align:center;padding:20px;background:linear-gradient(135deg,var(--pri-soft),transparent);border:1px dashed var(--pri);border-radius:14px;color:var(--pri-d);font-weight:700;font-size:.92rem}
.banner-soon b{font-family:'Outfit',sans-serif}
.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="/textbook/physics-11" class="hdr-back">
<svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
К курсу физики 11
</a>
</div>
<div>
<h1>Глава 8. Основы единой физической картины мира</h1>
<div class="hdr-sub">Современная естественнонаучная картина мира, эволюция физических теорий, четыре фундаментальных взаимодействия · §45</div>
</div>
</div>
</header>
<main>
<div class="intro-card">
<span class="intro-num">Глава 8</span>
<h2>Основы единой физической картины мира</h2>
<p>Современная естественнонаучная картина мира, эволюция физических теорий, четыре фундаментальных взаимодействия. Глава содержит 1 параграф и финальный этап с боссами.</p>
</div>
<div class="para-grid">
<article class="para-card">
<div class="para-num">§ 45</div>
<div class="para-body">
<h2 class="para-title">Современная естественнонаучная картина мира</h2>
<p class="para-sub">Эволюция представлений: механика → ЭМ → квант</p>
<div class="para-status">
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Будет добавлено в волне W14
</div>
</div>
</article>
</div>
<div class="banner-soon">
<b>Глава в разработке.</b> Полная реализация — в следующих волнах. Базовая библиотека <code>phys-fx.js</code> уже доступна.
</div>
</main>
<footer class="foot">
Физика — 11 класс · Глава 8 · LearnSpace
</footer>
</body>
</html>
+338
View File
@@ -0,0 +1,338 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Физика 11 класс — учебник</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"
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false})"></script>
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<style>
:root{
--bg:#ecfeff; --card:#fff;
--text:#0f172a; --muted:#475569;
--border:#a5f3fc;
--pri:#0891b2; --pri-d:#0e7490;
--pri-soft:#cffafe;
--sh:0 4px 16px rgba(8,145,178,.10);
--sh-h:0 12px 36px rgba(8,145,178,.18);
}
html.dark{
--bg:#062326; --card:#0a2e35;
--text:#cffafe; --muted:#67e8f9;
--border:#0f4750;
}
*{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}
.hdr{position:relative;background:linear-gradient(110deg,#155e75 0%,#0891b2 55%,#67e8f9 100%);color:#fff;padding:32px 24px 28px;overflow:hidden;border-bottom:2px solid rgba(165,243,252,.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(207,250,254,.12);line-height:1;pointer-events:none;user-select:none}
.hdr-inner{position:relative;z-index:1;max-width:1180px;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:.88;margin-top:4px}
.ic{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
main{max-width:1180px;margin:0 auto;padding:32px 24px 60px}
.prog-overall{background:linear-gradient(135deg,var(--pri-soft),rgba(103,232,249,.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,#0891b2,#67e8f9);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(8,145,178,.14);border-radius:5px;overflow:hidden;margin-top:6px}
.po-fill{height:100%;background:linear-gradient(90deg,var(--pri),#67e8f9);border-radius:5px;transition:width .5s}
.ch-grid{display:grid;grid-template-columns:1fr;gap:18px;margin-bottom:30px}
@media(min-width:680px){.ch-grid{grid-template-columns:1fr 1fr}}
@media(min-width:1100px){.ch-grid{grid-template-columns:repeat(4,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:-8px;top:-22px;font-size:5.2rem;font-weight:900;font-family:'Outfit',sans-serif;line-height:1;color:rgba(255,255,255,.20);pointer-events:none;letter-spacing:-.04em}
.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.05rem;font-weight:800;letter-spacing:-.01em;position:relative;z-index:1;line-height:1.3}
.ch-range{font-size:.82rem;opacity:.88;margin-top:4px;position:relative;z-index:1;font-weight:500}
.ch-body{padding:16px 20px 18px;display:flex;flex-direction:column;flex:1}
.ch-desc{font-size:.86rem;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;background:linear-gradient(90deg,var(--ch),var(--ch-d));transition:width .5s}
.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;background:linear-gradient(135deg,var(--ch),var(--ch-d));transition:filter .15s}
.ch-action:hover{filter:brightness(1.08)}
.banner-soon{margin-top:18px;text-align:center;padding:20px;background:linear-gradient(135deg,var(--pri-soft),transparent);border:1px dashed var(--pri);border-radius:14px;color:var(--pri-d);font-weight:700;font-size:.92rem}
.banner-soon b{font-family:'Outfit',sans-serif;display:block;margin-bottom:4px;font-size:1.05rem}
.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>Физика — 11 класс</h1>
<div class="hdr-sub">Жилко · Маркович · Сокольский (2021) · 8 глав · 45 параграфов</div>
</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>
</section>
<div class="ch-grid">
<a href="/textbook/physics-11-ch1" class="ch-card" style="--ch:#0891b2;--ch-d:#0e7490;--ch-soft:#cffafe">
<div class="ch-cover" style="background:linear-gradient(135deg,#155e75,#0891b2 60%,#a5f3fc)">
<div class="ch-cover-wm"></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-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/physics-11-ch2" class="ch-card" style="--ch:#7c3aed;--ch-d:#5b21b6;--ch-soft:#ede9fe">
<div class="ch-cover" style="background:linear-gradient(135deg,#5b21b6,#7c3aed 60%,#c4b5fd)">
<div class="ch-cover-wm"></div>
<div class="ch-num">Глава 2</div>
<div class="ch-title">Электромагнитные колебания и волны</div>
<div class="ch-range">§7–§13 + Финал</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/physics-11-ch3" class="ch-card" style="--ch:#d97706;--ch-d:#b45309;--ch-soft:#fef3c7">
<div class="ch-cover" style="background:linear-gradient(135deg,#b45309,#d97706 60%,#fcd34d)">
<div class="ch-cover-wm"></div>
<div class="ch-num">Глава 3</div>
<div class="ch-title">Оптика</div>
<div class="ch-range">§14–§23 + Финал</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/physics-11-ch4" class="ch-card" style="--ch:#2563eb;--ch-d:#1d4ed8;--ch-soft:#dbeafe">
<div class="ch-cover" style="background:linear-gradient(135deg,#1e3a8a,#2563eb 60%,#93c5fd)">
<div class="ch-cover-wm">c</div>
<div class="ch-num">Глава 4</div>
<div class="ch-title">Основы СТО</div>
<div class="ch-range">§24–§26 + Финал</div>
</div>
<div class="ch-body">
<div class="ch-desc">Принцип относительности Галилея, постулаты Эйнштейна, преобразования Лоренца, релятивистская динамика, E=mc².</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>
<a href="/textbook/physics-11-ch5" class="ch-card" style="--ch:#db2777;--ch-d:#9d174d;--ch-soft:#fce7f3">
<div class="ch-cover" style="background:linear-gradient(135deg,#831843,#db2777 60%,#fbcfe8)">
<div class="ch-cover-wm">γ</div>
<div class="ch-num">Глава 5</div>
<div class="ch-title">Фотоны. Действия света</div>
<div class="ch-range">§27–§29 + Финал</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-5">0%</span></div>
<div class="ch-prog-bar"><div class="ch-prog-fill" id="fill-5" style="width:0%"></div></div>
</div>
<div class="ch-action">
<span id="btn-5">Открыть главу</span>
<svg class="ic" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
</div>
</div>
</a>
<a href="/textbook/physics-11-ch6" class="ch-card" style="--ch:#10b981;--ch-d:#047857;--ch-soft:#d1fae5">
<div class="ch-cover" style="background:linear-gradient(135deg,#065f46,#10b981 60%,#a7f3d0)">
<div class="ch-cover-wm"></div>
<div class="ch-num">Глава 6</div>
<div class="ch-title">Физика атома</div>
<div class="ch-range">§30–§34 + Финал</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-6">0%</span></div>
<div class="ch-prog-bar"><div class="ch-prog-fill" id="fill-6" style="width:0%"></div></div>
</div>
<div class="ch-action">
<span id="btn-6">Открыть главу</span>
<svg class="ic" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
</div>
</div>
</a>
<a href="/textbook/physics-11-ch7" class="ch-card" style="--ch:#dc2626;--ch-d:#991b1b;--ch-soft:#fee2e2">
<div class="ch-cover" style="background:linear-gradient(135deg,#7f1d1d,#dc2626 60%,#fca5a5)">
<div class="ch-cover-wm"></div>
<div class="ch-num">Глава 7</div>
<div class="ch-title">Ядерная физика и элементарные частицы</div>
<div class="ch-range">§35–§44 + Финал</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-7">0%</span></div>
<div class="ch-prog-bar"><div class="ch-prog-fill" id="fill-7" style="width:0%"></div></div>
</div>
<div class="ch-action">
<span id="btn-7">Открыть главу</span>
<svg class="ic" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
</div>
</div>
</a>
<a href="/textbook/physics-11-ch8" class="ch-card" style="--ch:#6366f1;--ch-d:#4338ca;--ch-soft:#e0e7ff">
<div class="ch-cover" style="background:linear-gradient(135deg,#3730a3,#6366f1 60%,#c7d2fe)">
<div class="ch-cover-wm"></div>
<div class="ch-num">Глава 8</div>
<div class="ch-title">Основы единой физической картины мира</div>
<div class="ch-range">§45 + Финал</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-8">0%</span></div>
<div class="ch-prog-bar"><div class="ch-prog-fill" id="fill-8" style="width:0%"></div></div>
</div>
<div class="ch-action">
<span id="btn-8">Открыть главу</span>
<svg class="ic" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
</div>
</div>
</a>
</div>
<div class="banner-soon">
<b>Курс в активной разработке (W0)</b>
Инфраструктура готова: миграция БД, библиотека phys-fx.js (Oscillogram, SpringMass, Pendulum) и 8 stub-страниц глав. Реализация по плану PLAN_FIZIKA_11.md — 15 волн (~26 сессий).
</div>
</main>
<footer class="foot">
Интерактивный учебник «Физика — 11 класс» · LearnSpace
</footer>
<script>
'use strict';
var TOTAL = 45;
var CH_PARA = {'physics-11-ch1': 6, 'physics-11-ch2': 7, 'physics-11-ch3': 10, 'physics-11-ch4': 3, 'physics-11-ch5': 3, 'physics-11-ch6': 5, 'physics-11-ch7': 10, 'physics-11-ch8': 1};
var CH_IDX = {'physics-11-ch1': 1, 'physics-11-ch2': 2, 'physics-11-ch3': 3, 'physics-11-ch4': 4, 'physics-11-ch5': 5, 'physics-11-ch6': 6, 'physics-11-ch7': 7, 'physics-11-ch8': 8};
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 = 'Открыть главу';
}
}
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] || 1;
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 + '%';
}
function loadProgress(){
if (typeof window.LS === 'undefined' || typeof window.LS.api !== 'function'){
renderProgress([]); return;
}
window.LS.api('/api/textbooks/physics-11/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>