diff --git a/frontend/js/phys-fx.js b/frontend/js/phys-fx.js
index e5946b1..e11e36b 100644
--- a/frontend/js/phys-fx.js
+++ b/frontend/js/phys-fx.js
@@ -1540,4 +1540,196 @@ class TwoLensSystem {
}
P.TwoLensSystem = TwoLensSystem;
+/* ============================================================ */
+/* GammaPlot — график γ(β) и τ/τ₀, L/L₀ */
+/* ============================================================ */
+
+class GammaPlot {
+ constructor(container, opts){
+ opts = opts || {};
+ this.el = (typeof container === 'string') ? document.querySelector(container) : container;
+ this.W = opts.width || 580;
+ this.H = opts.height || 280;
+ this.beta = opts.beta !== undefined ? opts.beta : 0.5; /* v/c */
+ this.color = opts.color || '#2563eb';
+ this.paused = true;
+ this.render();
+ }
+ setBeta(v){ this.beta = Math.max(0, Math.min(0.999, v)); this.render(); }
+ update(){}
+ render(){
+ if (!this.el) return;
+ const W = this.W, H = this.H;
+ const pad = 40;
+ const left = pad, right = W - pad - 100, top = 30, bot = H - 40;
+ let svg = util.svgFrame(W, H, {bg:'#f8fafc'});
+ /* Сетка */
+ svg += '';
+ for (let i = 0; i <= 10; i++){
+ const x = left + i * (right - left) / 10;
+ svg += ' ';
+ }
+ for (let i = 0; i <= 6; i++){
+ const y = top + i * (bot - top) / 6;
+ svg += ' ';
+ }
+ svg += ' ';
+ /* Оси */
+ svg += ' ';
+ svg += ' ';
+ /* Метки осей */
+ svg += 'β = v/c ';
+ svg += 'γ ';
+ /* γ — растёт; ограничим до 6 */
+ let pts = '';
+ for (let i = 0; i <= 100; i++){
+ const b = i / 100 * 0.99;
+ const g = 1 / Math.sqrt(1 - b * b);
+ const x = left + b * (right - left);
+ const y = bot - Math.min(6, g) * (bot - top) / 6;
+ pts += x.toFixed(1) + ',' + y.toFixed(1) + ' ';
+ }
+ svg += ' ';
+ /* γ = 1 базовая линия */
+ svg += ' ';
+ svg += '1 ';
+ /* Текущая точка */
+ const g = 1 / Math.sqrt(1 - this.beta * this.beta);
+ const cx = left + this.beta * (right - left);
+ const cy = bot - Math.min(6, g) * (bot - top) / 6;
+ svg += ' ';
+ svg += ' ';
+ /* Подпись значения */
+ const panelX = right + 12;
+ svg += 'β = ' + this.beta.toFixed(3) + ' ';
+ svg += 'γ = ' + g.toFixed(3) + ' ';
+ svg += 'τ = γτ₀ ';
+ svg += 'L = L₀/γ ';
+ svg += 'τ/τ₀ = ' + g.toFixed(2) + ' ';
+ svg += 'L/L₀ = ' + (1 / g).toFixed(2) + ' ';
+ svg += 'γ = 1/√(1 - β²) ';
+ svg += '';
+ this.el.innerHTML = svg;
+ }
+}
+P.GammaPlot = GammaPlot;
+
+/* ============================================================ */
+/* TimeDilation — двое часов: «покоящиеся» и «движущиеся» */
+/* ============================================================ */
+
+class TimeDilation {
+ constructor(container, opts){
+ opts = opts || {};
+ this.el = (typeof container === 'string') ? document.querySelector(container) : container;
+ this.W = opts.width || 600;
+ this.H = opts.height || 240;
+ this.beta = opts.beta !== undefined ? opts.beta : 0.5;
+ this.t = 0;
+ this.paused = false;
+ this._render();
+ util.subscribe(this);
+ util.observe(this);
+ }
+ setBeta(v){ this.beta = Math.max(0, Math.min(0.99, v)); }
+ update(dt){ this.t += dt; }
+ drawClock(svg, cx, cy, r, time, label, color){
+ let s = svg;
+ s += ' ';
+ /* Метки часов 12, 3, 6, 9 */
+ for (let i = 0; i < 12; i++){
+ const a = i * Math.PI / 6;
+ const x1 = cx + (r - 6) * Math.sin(a), y1 = cy - (r - 6) * Math.cos(a);
+ const x2 = cx + (r - 2) * Math.sin(a), y2 = cy - (r - 2) * Math.cos(a);
+ s += ' ';
+ }
+ /* Стрелка секундная (один оборот = 6 «времени») */
+ const a = (time / 6) * 2 * Math.PI;
+ const hx = cx + (r - 12) * Math.sin(a), hy = cy - (r - 12) * Math.cos(a);
+ s += ' ';
+ s += ' ';
+ s += '' + label + ' ';
+ s += 't = ' + time.toFixed(2) + ' с ';
+ return s;
+ }
+ render(){
+ if (!this.el) return;
+ const W = this.W, H = this.H;
+ const g = 1 / Math.sqrt(1 - this.beta * this.beta);
+ /* Часы покоя — реальное время */
+ const t0 = this.t;
+ /* Движущиеся — идут медленнее в γ раз для наблюдателя */
+ const tmov = this.t / g;
+ let svg = util.svgFrame(W, H, {bg:'#f8fafc'});
+ svg = this.drawClock(svg, 140, 100, 55, t0, 'часы наблюдателя', '#0f172a');
+ svg = this.drawClock(svg, W - 140, 100, 55, tmov, 'часы в движ. системе', '#dc2626');
+ /* Стрелка движения */
+ svg += ' ';
+ svg += ' ';
+ svg += 'v → · β = ' + this.beta.toFixed(2) + ' · γ = ' + g.toFixed(2) + ' ';
+ svg += 'Δτ = γ · Δτ₀ (движущиеся часы идут медленнее) ';
+ svg += '';
+ this.el.innerHTML = svg;
+ }
+ _render(){ this.render(); }
+}
+P.TimeDilation = TimeDilation;
+
+/* ============================================================ */
+/* LengthContraction — стержень в покое и в движении */
+/* ============================================================ */
+
+class LengthContraction {
+ constructor(container, opts){
+ opts = opts || {};
+ this.el = (typeof container === 'string') ? document.querySelector(container) : container;
+ this.W = opts.width || 600;
+ this.H = opts.height || 220;
+ this.beta = opts.beta !== undefined ? opts.beta : 0.5;
+ this.L0 = opts.L0 !== undefined ? opts.L0 : 320;
+ this.paused = true;
+ this.render();
+ }
+ setBeta(v){ this.beta = Math.max(0, Math.min(0.99, v)); this.render(); }
+ update(){}
+ render(){
+ if (!this.el) return;
+ const W = this.W, H = this.H;
+ const g = 1 / Math.sqrt(1 - this.beta * this.beta);
+ const L = this.L0 / g;
+ let svg = util.svgFrame(W, H, {bg:'#f8fafc'});
+ /* Подпись */
+ svg += 'L = L₀ · √(1 - β²) = L₀/γ ';
+ /* Стержень в покое */
+ const cx = W / 2;
+ const y1 = 60;
+ svg += 'покой: ';
+ svg += ' ';
+ /* Деления */
+ for (let i = 0; i <= 10; i++){
+ const x = cx - this.L0/2 + i * this.L0 / 10;
+ svg += ' ';
+ }
+ svg += 'L₀ = ' + this.L0 + ' (собственная длина) ';
+ /* Стержень в движении */
+ const y2 = 140;
+ svg += 'движется: ';
+ svg += ' ';
+ for (let i = 0; i <= 10; i++){
+ const x = cx - L/2 + i * L / 10;
+ svg += ' ';
+ }
+ /* Стрелка скорости */
+ svg += ' ';
+ svg += ' ';
+ svg += 'v ';
+ svg += 'L = ' + L.toFixed(1) + ' · L/L₀ = ' + (1/g).toFixed(3) + ' ';
+ /* Параметры */
+ svg += 'β = ' + this.beta.toFixed(2) + ' · γ = ' + g.toFixed(2) + ' ';
+ svg += '';
+ this.el.innerHTML = svg;
+ }
+}
+P.LengthContraction = LengthContraction;
+
})();
diff --git a/frontend/textbooks/physics_11_ch4.html b/frontend/textbooks/physics_11_ch4.html
index 0c0219a..2323523 100644
--- a/frontend/textbooks/physics_11_ch4.html
+++ b/frontend/textbooks/physics_11_ch4.html
@@ -1,143 +1,962 @@
-
+
-
-Физика 11 · Глава 4 · Основы СТО
-
+Физика 11 · Глава 4 · «Основы СТО»
+
-
+
+
-
+
-
-
- К курсу физики 11
-
+
Физика 11 · Глава 4
+
Основы СТО · принцип относительности Эйнштейна, замедление времени, сокращение длин, E = mc²
-
-
Глава 4. Основы СТО
-
Принцип относительности Галилея, постулаты Эйнштейна, преобразования Лоренца, релятивистская динамика, E=mc² · §24–§26
+
-
+
+
-
-
Глава 4
-
Основы СТО
-
Принцип относительности Галилея, постулаты Эйнштейна, преобразования Лоренца, релятивистская динамика, E=mc². Глава содержит 3 параграфа и финальный этап с боссами.
-
-
-
-
-
- § 24
-
-
Принцип относ. Галилея и ЭМ явления. Эксп. предпосылки СТО
-
Опыт Майкельсона – Морли
-
-
- Будет добавлено в волне W8
+
+ Основы СТО — революция Эйнштейна
+ Глава о том, как в начале XX века Альберт Эйнштейн пересмотрел понятия пространства и времени. 3 параграфа + финал с 3 интегральными боссами.
+
+
Начать § 24
+
+
Прогресс по главе
+
+
0%
+
-
+
-
- § 25
-
-
Постулаты специальной теории относительности
-
$\Delta t = \gamma\Delta t_0$, $l = l_0/\gamma$
-
-
- Будет добавлено в волне W8
-
-
-
+
+
+
+
+
+
-
- § 26
-
-
Элементы релятивистской динамики. Взаимосвязь массы и энергии
-
$E_0 = mc^2$, $E^2 = (mc^2)^2 + (pc)^2$
-
-
- Будет добавлено в волне W8
-
-
-
-
-
- Глава в разработке. Полная реализация — в следующих волнах. Базовая библиотека phys-fx.js уже доступна.
-
-
+
-
+
+
+
+