diff --git a/assets/themes/sonic/environments/ancient-ruins.png b/assets/themes/sonic/environments/ancient-ruins.png
new file mode 100644
index 0000000..46839b2
Binary files /dev/null and b/assets/themes/sonic/environments/ancient-ruins.png differ
diff --git a/assets/themes/sonic/environments/beach-sunset.png b/assets/themes/sonic/environments/beach-sunset.png
new file mode 100644
index 0000000..5367b9e
Binary files /dev/null and b/assets/themes/sonic/environments/beach-sunset.png differ
diff --git a/assets/themes/sonic/environments/city-street.png b/assets/themes/sonic/environments/city-street.png
new file mode 100644
index 0000000..e85907f
Binary files /dev/null and b/assets/themes/sonic/environments/city-street.png differ
diff --git a/assets/themes/sonic/environments/green-hill.png b/assets/themes/sonic/environments/green-hill.png
new file mode 100644
index 0000000..575e3d4
Binary files /dev/null and b/assets/themes/sonic/environments/green-hill.png differ
diff --git a/assets/themes/sonic/environments/neon-city.png b/assets/themes/sonic/environments/neon-city.png
new file mode 100644
index 0000000..f0fdbc5
Binary files /dev/null and b/assets/themes/sonic/environments/neon-city.png differ
diff --git a/assets/themes/sonic/environments/sky-highway.png b/assets/themes/sonic/environments/sky-highway.png
new file mode 100644
index 0000000..0712506
Binary files /dev/null and b/assets/themes/sonic/environments/sky-highway.png differ
diff --git a/assets/themes/sonic/environments/space-ark.png b/assets/themes/sonic/environments/space-ark.png
new file mode 100644
index 0000000..d24e760
Binary files /dev/null and b/assets/themes/sonic/environments/space-ark.png differ
diff --git a/assets/themes/sonic/environments/volcano-zone.png b/assets/themes/sonic/environments/volcano-zone.png
new file mode 100644
index 0000000..ffc41d6
Binary files /dev/null and b/assets/themes/sonic/environments/volcano-zone.png differ
diff --git a/assets/themes/sonic/environments/winter-forest.png b/assets/themes/sonic/environments/winter-forest.png
new file mode 100644
index 0000000..ab58f7b
Binary files /dev/null and b/assets/themes/sonic/environments/winter-forest.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-01.png b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-01.png
index 1f1eb87..3d218ad 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-01.png and b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-01.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-02.png b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-02.png
index 643c3b3..5079cb1 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-02.png and b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-02.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-03.png b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-03.png
index af448f7..cd6481a 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-03.png and b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-03.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-04.png b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-04.png
index 59ccbc0..3023bab 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-04.png and b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-04.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-05.png b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-05.png
index 888d169..4d63af1 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-05.png and b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-05.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-06.png b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-06.png
index 3a40af9..7a9cc0a 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-06.png and b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-06.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-07.png b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-07.png
index aa04023..0b6b3cb 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-07.png and b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-07.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-08.png b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-08.png
index 7e768da..0a382cf 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-08.png and b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-08.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-09.png b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-09.png
index 216855e..4cccf3e 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-09.png and b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-09.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-10.png b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-10.png
index df45a22..13d709c 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-10.png and b/assets/themes/sonic/heroes/sonic-shadow-push/shadow-push-10.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-01.png b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-01.png
index 113d8cd..a85b81e 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-01.png and b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-01.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-02.png b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-02.png
index a198a8a..9390688 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-02.png and b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-02.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-03.png b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-03.png
index 54ad199..82a2a12 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-03.png and b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-03.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-04.png b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-04.png
index 2bda0eb..50e0d12 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-04.png and b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-04.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-05.png b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-05.png
index bfd0d19..84b9ff6 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-05.png and b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-05.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-06.png b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-06.png
index 83a6ad6..46b6027 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-06.png and b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-06.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-07.png b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-07.png
index 5ac25f6..2ef7c70 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-07.png and b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-07.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-08.png b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-08.png
index b18d0aa..1bdf2b2 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-08.png and b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-08.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-09.png b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-09.png
index eb22b01..488de48 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-09.png and b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-09.png differ
diff --git a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-10.png b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-10.png
index 5c33105..eb2f4f7 100644
Binary files a/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-10.png and b/assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-10.png differ
diff --git a/assets/themes/sonic/items/conduit/conduit1.png b/assets/themes/sonic/items/conduit/conduit1.png
new file mode 100644
index 0000000..60255a3
Binary files /dev/null and b/assets/themes/sonic/items/conduit/conduit1.png differ
diff --git a/assets/themes/sonic/items/conduit/conduit2.png b/assets/themes/sonic/items/conduit/conduit2.png
new file mode 100644
index 0000000..fcbec30
Binary files /dev/null and b/assets/themes/sonic/items/conduit/conduit2.png differ
diff --git a/tasks/crystal-battery/CLAUDE.md b/tasks/crystal-battery/CLAUDE.md
new file mode 100644
index 0000000..bd768a2
--- /dev/null
+++ b/tasks/crystal-battery/CLAUDE.md
@@ -0,0 +1,106 @@
+# Crystal Battery Task Type
+
+**Theme:** sonic (`assets/themes/sonic/`) + nms placeholders (`assets/themes/nms/`)
+
+Sonic and Shadow take turns charging a 10-cell crystal battery. One hero fills N cells, the child figures out how many the other hero needs to complete all 10. Practices **complements of 10** (making 10).
+
+## Math Concept
+
+Given:
+- Battery capacity: always **10** cells
+- Hero A fills **N** cells (1 < N < 10), shown with crystal icons
+- Child writes **N** in small input near Hero A
+- Child writes **10 - N** in large input near Hero B
+- Answer: always 10 - N
+
+## Layout
+
+- **Page:** A4 (210mm x 297mm), white background
+- **Header:** 20mm — title centered, small Sonic (left) + Shadow (right) icons
+- **Footer:** 25mm — NMS planet placeholder with gradient fade
+- **Content:** 7 battery sections per page, distributed evenly (flex column, justify-between)
+- **Section height:** ~30mm
+
+## Section Layout
+
+Full-width horizontal strip (~194mm wide inside 8mm page padding):
+
+```
+┌──────────┬────────────────────────────────┬──────────┐
+│ Hero A │ BATTERY (10 cells) │ Hero B │
+│ push │ [▣][▣][▣]...[ ][ ][ ] │ push │
+│ [__] │ ← N filled (10-N) empty → │ [____] │
+└──────────┴────────────────────────────────┴──────────┘
+ 28mm ~138mm 28mm
+```
+
+**Odd sections** (1,3,5,7): Sonic fills from left, Shadow answers
+**Even sections** (2,4,6): Shadow fills from right, Sonic answers
+
+## Battery Design
+
+- 10 rectangular cells in horizontal row (flex)
+- Width: 80mm, Height: 14mm
+- Border: 2px solid #334155, border-radius: 3mm
+- Terminal nub on right side (decorative, 3mm wide)
+- **Filled cells:** green gradient (#22c55e → #16a34a) for Sonic, red gradient (#ef4444 → #dc2626) for Shadow + SVG diamond crystal icon
+- **Empty cells:** #e2e8f0 background, dashed border, no icon
+
+## Crystal Placeholders
+
+Inline SVG diamond shapes (temporary until proper crystal PNGs are generated):
+- Sonic: green (#22c55e) with darker stroke (#15803d)
+- Shadow: red (#ef4444) with darker stroke (#b91c1c)
+
+## Input Fields
+
+- **Small input** (near filling hero): 10mm x 7mm, border: 1.5px solid #a5b4fc, rounded 1.5mm
+- **Large input** (near answering hero): 14mm x 9mm, border: 2px solid #6366f1, rounded 2mm
+
+## Hero Variants
+
+Cycle through push variants sequentially across sections:
+- Section 1: sonic-push-01 + shadow-push-01
+- Section 2: sonic-push-02 + shadow-push-02
+- Continue across pages (21 sections total, wraps around 10 variants)
+
+Assets: `assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-{01-10}.png` and `shadow-push-{01-10}.png`
+
+## Color Palette
+
+| Element | Color |
+|---------|-------|
+| Title | `text-indigo-950` |
+| Subtitle | `text-indigo-400` |
+| Sonic crystals | `#22c55e` (green-500) |
+| Shadow crystals | `#ef4444` (red-500) |
+| Battery border | `#334155` (slate-700) |
+| Empty cells | `#e2e8f0` (slate-200) |
+| Small input border | `#a5b4fc` (indigo-300) |
+| Large input border | `#6366f1` (indigo-500) |
+
+## Problem Range
+
+N: 1-9 (number of crystals the filling hero throws)
+Answer: 10 - N (always 1-9)
+
+## Difficulty Progression
+
+**Page 1 (Easy):** N = 9, 8, 9, 7, 8, 9, 7 → complements 1-3
+**Page 2 (Medium):** N = 6, 5, 4, 6, 5, 4, 6 → complements 4-6
+**Page 3 (Hard):** N = 3, 2, 1, 3, 2, 1, 4 → complements 6-9
+
+## Asset Conventions
+
+- **Heroes:** `assets/themes/sonic/heroes/sonic-shadow-push/sonic-push-{01-10}.png`, `shadow-push-{01-10}.png`
+- **Footer images (placeholder):** `assets/themes/nms/footers/planet{1-9}.jpeg`
+- **Crystals:** SVG placeholders (future: `assets/themes/sonic/items/crystals/`)
+
+## Title & Subtitle
+
+- **Title:** "Кристальная Батарея"
+- **Subtitle:** "Соник и Шэдоу заряжают батарею! Сколько кристаллов нужно добавить?"
+
+## Scripts
+
+- `scripts/generate.mjs` — template + data → output pipeline (minimal, no transforms initially)
diff --git a/tasks/crystal-battery/docs/crystal-battery-1.md b/tasks/crystal-battery/docs/crystal-battery-1.md
new file mode 100644
index 0000000..80f7ce7
--- /dev/null
+++ b/tasks/crystal-battery/docs/crystal-battery-1.md
@@ -0,0 +1,54 @@
+# Crystal Battery 1
+
+Sonic and Shadow take turns charging a crystal battery. Each section shows one hero filling N cells out of 10. The child writes how many crystals the hero threw (N) and how many the other hero needs to add (10 - N).
+
+## Pages
+
+### Page 1 — Easy (complements 1-3)
+
+| Section | Filler | N | Answer (10-N) | Sonic variant | Shadow variant |
+|---------|--------|---|---------------|---------------|----------------|
+| 1 | Sonic | 9 | 1 | sonic-push-01 | shadow-push-01 |
+| 2 | Shadow | 8 | 2 | sonic-push-02 | shadow-push-02 |
+| 3 | Sonic | 9 | 1 | sonic-push-03 | shadow-push-03 |
+| 4 | Shadow | 7 | 3 | sonic-push-04 | shadow-push-04 |
+| 5 | Sonic | 8 | 2 | sonic-push-05 | shadow-push-05 |
+| 6 | Shadow | 9 | 1 | sonic-push-06 | shadow-push-06 |
+| 7 | Sonic | 7 | 3 | sonic-push-07 | shadow-push-07 |
+
+Footer: planet1.jpeg
+
+### Page 2 — Medium (complements 4-6)
+
+| Section | Filler | N | Answer (10-N) | Sonic variant | Shadow variant |
+|---------|--------|---|---------------|---------------|----------------|
+| 1 | Sonic | 6 | 4 | sonic-push-08 | shadow-push-08 |
+| 2 | Shadow | 5 | 5 | sonic-push-09 | shadow-push-09 |
+| 3 | Sonic | 4 | 6 | sonic-push-10 | shadow-push-10 |
+| 4 | Shadow | 6 | 4 | sonic-push-01 | shadow-push-01 |
+| 5 | Sonic | 5 | 5 | sonic-push-02 | shadow-push-02 |
+| 6 | Shadow | 4 | 6 | sonic-push-03 | shadow-push-03 |
+| 7 | Sonic | 6 | 4 | sonic-push-04 | shadow-push-04 |
+
+Footer: planet2.jpeg
+
+### Page 3 — Hard (complements 6-9)
+
+| Section | Filler | N | Answer (10-N) | Sonic variant | Shadow variant |
+|---------|--------|---|---------------|---------------|----------------|
+| 1 | Sonic | 3 | 7 | sonic-push-05 | shadow-push-05 |
+| 2 | Shadow | 2 | 8 | sonic-push-06 | shadow-push-06 |
+| 3 | Sonic | 1 | 9 | sonic-push-07 | shadow-push-07 |
+| 4 | Shadow | 3 | 7 | sonic-push-08 | shadow-push-08 |
+| 5 | Sonic | 2 | 8 | sonic-push-09 | shadow-push-09 |
+| 6 | Shadow | 1 | 9 | sonic-push-10 | shadow-push-10 |
+| 7 | Sonic | 4 | 6 | sonic-push-01 | shadow-push-01 |
+
+Footer: planet3.jpeg
+
+## Notes
+
+- Sonic crystals are green, Shadow crystals are red
+- Crystal assets are SVG placeholders — will be replaced with generated PNGs later
+- Footer images are NMS theme placeholders
+- Hero images are from `assets/themes/sonic/heroes/sonic-shadow-push/`
diff --git a/tasks/crystal-battery/docs/crystal-battery-1.template.html b/tasks/crystal-battery/docs/crystal-battery-1.template.html
new file mode 100644
index 0000000..ac2615a
--- /dev/null
+++ b/tasks/crystal-battery/docs/crystal-battery-1.template.html
@@ -0,0 +1,832 @@
+
+
+
+
+
+
+
+
+
+ Кристальная Батарея
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tasks/crystal-battery/index.html b/tasks/crystal-battery/index.html
new file mode 100644
index 0000000..3ee639e
--- /dev/null
+++ b/tasks/crystal-battery/index.html
@@ -0,0 +1,179 @@
+
+
+
+
+
+ Crystal Battery — Space Math Adventures
+
+
+
+
+
+
+
+
+
← All Categories
+
+
+
+
+
+
+
+
+
+
Crystal Battery 1
+
+ 3 pages
+ Easy → Hard
+ 7 sections per page • Complements of 10 • Sonic & Shadow theme
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tasks/crystal-battery/scripts/generate.mjs b/tasks/crystal-battery/scripts/generate.mjs
new file mode 100644
index 0000000..1666ce7
--- /dev/null
+++ b/tasks/crystal-battery/scripts/generate.mjs
@@ -0,0 +1,47 @@
+#!/usr/bin/env node
+
+/**
+ * Generate output HTML from template + data for crystal-battery documents.
+ *
+ * Usage: node generate.mjs
+ * Example: node generate.mjs crystal-battery-1
+ *
+ * Reads: docs/.template.html
+ * Reads: docs/.data.json (optional)
+ * Writes: docs/.output.html
+ */
+
+import { readFileSync, writeFileSync, existsSync } from 'fs';
+import { join, dirname } from 'path';
+import { fileURLToPath } from 'url';
+import { postGenerate } from '../../../src/scripts/post-generate.mjs';
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+const docsDir = join(__dirname, '..', 'docs');
+
+const docId = process.argv[2];
+if (!docId) {
+ console.error('Usage: node generate.mjs ');
+ process.exit(1);
+}
+
+const templatePath = join(docsDir, `${docId}.template.html`);
+const dataPath = join(docsDir, `${docId}.data.json`);
+const outputPath = join(docsDir, `${docId}.output.html`);
+
+if (!existsSync(templatePath)) {
+ console.error(`Template not found: ${templatePath}`);
+ process.exit(1);
+}
+
+let html = readFileSync(templatePath, 'utf-8');
+
+if (existsSync(dataPath)) {
+ const data = JSON.parse(readFileSync(dataPath, 'utf-8'));
+ // No transforms defined yet — data.json support reserved for future editor
+ console.log(`Data file found (${data.pages?.length || 0} pages), no transforms applied yet`);
+}
+
+writeFileSync(outputPath, html);
+console.log(`Generated: ${outputPath}`);
+await postGenerate(outputPath);
diff --git a/tasks/index.html b/tasks/index.html
index 912bf41..14c8977 100644
--- a/tasks/index.html
+++ b/tasks/index.html
@@ -231,6 +231,20 @@
+
+
+
+
+
+
+
Crystal Battery
+
Sonic and Shadow take turns charging a crystal battery! One hero fills cells with crystals, the child figures out how many the other hero needs. Practices complements of 10.
+
+ 1 worksheet
+ Making 10
+
+
+