diff --git a/.claude/commands/new-doc.md b/.claude/commands/new-doc.md new file mode 100644 index 0000000..c69b2ca --- /dev/null +++ b/.claude/commands/new-doc.md @@ -0,0 +1,58 @@ +--- +description: Create a new math worksheet document (JSON config + HTML + PDF) +allowed-tools: [Read, Write, Edit, Glob, Grep, Bash, AskUserQuestion] +--- + +You are creating a new math worksheet document. Follow these steps: + +## Step 1: Gather requirements + +Use AskUserQuestion to ask the user (ask all at once, not one by one): + +1. **Theme** — what visual theme? (space, forest, ocean, etc.). Currently only "space" theme with `space-base` template is available. +2. **Pages** — how many pages and what math task for each page? E.g. "Page 1: addition A+B where A 1-20, B 1-10. Page 2: multiplication A×B where A,B 1-5" +3. **Texts** — title, subtitle, and footer bubble text (or use defaults from theme) +4. **Document name** — filename for the output (used as `tasks/.json` and `output/html/.html`) + +## Step 2: Create JSON task config + +Read `tasks/space-exploration-1.json` as a format reference. + +Create a new JSON file in `tasks/.json` with: +- Unique `id` matching the filename +- `labels` with title/subtitle/footerBubble from user input +- `theme` matching the chosen visual theme +- `layout` with columns and problemsPerPage +- `pages` array — one entry per page with: + - `task`: free-text description of the math problems + - `problemCount`: number of problems (typically 20) + - `heroImage`: pick from available hero images (for space: `assets/hero-images/spaceship{1-6}.jpeg`) + - `footerImage`: pick from available footer images (for space: `assets/footers/planet{1-6}.jpeg`) + - `heroDirection`: alternate between `row` and `row-reverse` across pages + +Use different hero/footer images for each page. + +## Step 3: Generate HTML + +1. Read `src/templates/space-base.html` (structure reference) +2. Read `src/examples/space-worksheet.html` (finished output reference) +3. Read the JSON config you just created + +Generate the HTML file at `output/html/.html`: +- For each page, generate concrete math problems based on the `task` text +- Assign unique icons from `assets/icons/pack1/` — no icon should repeat across the entire document. Shuffle minerals and plants together randomly +- Randomize problem card alignment (justify-start, justify-center, justify-end) — no visible pattern +- Use `break-after: page` between pages (not on the last page) +- Do NOT use `overflow-hidden` on the footer container (causes PDF hairline artifact) + +## Step 4: Generate PDF + +Run: `npm run pdf -- output/html/.html` + +## Step 5: Report + +Tell the user: +- Path to JSON config +- Path to HTML file +- Path to PDF file +- Summary of what was generated (pages, problem types) diff --git a/CLAUDE.md b/CLAUDE.md index f698767..f5d1080 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,11 +14,6 @@ npm run dev # CSS watch + preview server (concurrent) npm run pdf -- # Convert HTML file to PDF ``` -Generate problems from a task config: -```bash -node src/scripts/generate-problems.mjs tasks/.json -``` - Generate images via Banatie API: ```bash node src/scripts/banatie.mjs --type background --prompt "forest theme" --output assets/backgrounds/forest.png @@ -30,10 +25,10 @@ node src/scripts/banatie.mjs --type icon --prompt "golden star" --output assets/ ``` src/ styles/main.css — Tailwind source with A4/print styles - templates/space-base.html — Base template (reference example, see below) + templates/space-base.html — Base template (layout/styling reference) + examples/space-worksheet.html — Finished 3-page example (output reference) scripts/ generate-pdf.mjs — HTML → PDF via Puppeteer - generate-problems.mjs — JSON task → concrete problem list banatie.mjs — Banatie API client for image generation tasks/ — JSON task definition files assets/ @@ -49,69 +44,75 @@ output/ ## JSON Task Format -Each task is a JSON file in `tasks/` with this structure: +Each task is a JSON file in `tasks/` defining a multi-page document. See `tasks/space-exploration-1.json` for a real example. ```json { - "id": "multiply-2-3", - "title": "Умножение на 2 и 3", - "description": "Worksheet for practicing multiplication by 2 and 3", - "template": "{a} × {b} = ___", - "variables": { - "a": { "type": "range", "min": 1, "max": 10 }, - "b": { "type": "set", "values": [2, 3] } + "id": "space-exploration-1", + "title": "Исследуй Планету", + "description": "3-page space worksheet: addition ±, multiply by 5 ±, multiplication table ±", + "labels": { + "title": "Исследуй Планету", + "subtitle": "Собери ресурсы, решая примеры!", + "footerBubble": "Итого собрано на планете:" + }, + "theme": { + "style": "space", + "template": "space-base", + "icons": "assets/icons/pack1/" }, - "problemCount": 20, "layout": { "columns": 2, "problemsPerPage": 20 }, - "labels": { - "title": "Умножение", - "subtitle": "Реши примеры", - "name": "Имя: _______________", - "date": "Дата: _______________" - }, - "theme": { - "background": "assets/backgrounds/forest.png", - "icons": "assets/icons/stars/", - "iconReward": 1 - } + "pages": [ + { + "task": "A + B ± C, где A от 8 до 16, B от 4 до 8, C от 1 до 3. Знак ± выбирается случайно", + "problemCount": 20, + "heroImage": "assets/hero-images/spaceship2.jpeg", + "footerImage": "assets/footers/planet3.jpeg", + "heroDirection": "row-reverse" + } + ] } ``` ### Fields -- **template** — problem template with `{variable}` placeholders -- **variables** — each variable is either `range` (min/max) or `set` (explicit values) -- **problemCount** — how many problems to generate +- **pages[]** — array of pages, each with its own task and images +- **pages[].task** — free-text description of problems to generate (Claude reads this and creates concrete expressions) +- **pages[].problemCount** — how many problems on this page +- **pages[].heroImage** — path to hero image for this page +- **pages[].footerImage** — path to footer panorama for this page +- **pages[].heroDirection** — `row` (hero left) or `row-reverse` (hero right) - **layout.columns** — 1 or 2 column layout - **layout.problemsPerPage** — max problems per A4 page - **labels** — all visible text (no hardcoded language) -- **theme.background** — path to background image -- **theme.icons** — path to icon directory (for collectible rewards) -- **theme.iconReward** — show an icon every N problems solved +- **theme.style** — visual theme name (e.g. "space") +- **theme.template** — which base template to use (e.g. "space-base") +- **theme.icons** — path to icon directory for problem cards ## Space Base Template -Reference example: `src/templates/space-base.html` +Base template: `src/templates/space-base.html` +Finished example: `src/examples/space-worksheet.html` (3-page output matching `tasks/space-exploration-1.json`) -This is the base visual design for all space-themed worksheets. When generating a new worksheet, use this file as the source of truth for layout, styling, and structure. **Read it first**, then produce a new HTML with these variations: +The base template defines the visual design for all space-themed worksheets. The example shows a complete generated document. When generating a new worksheet, **read both files first**, then produce a new HTML with these variations: ### What to vary per worksheet 1. **Hero image** — pick one from `assets/hero-images/spaceship{1-6}.jpeg` 2. **Footer image** — pick one from `assets/footers/planet{1-6}.jpeg` 3. **Hero position** — set CSS variable `--hero-direction: row` (hero left) or `row-reverse` (hero right) -4. **Problem icons** — randomly pick from `assets/icons/pack1/` (minerals and plants, any variant `{name}-{row}-{col}.png`) +4. **Problem icons** — pick from `assets/icons/pack1/` (minerals and plants, any variant `{name}-{row}-{col}.png`). **Every icon must be unique across the entire document** (no repeats across pages). Shuffle minerals and plants together randomly — do not sort by type 5. **Problem alignment** — for each problem card, randomly assign `justify-start`, `justify-center`, or `justify-end` within its grid column. No repeating patterns — should look chaotic/scattered 6. **Title, subtitle, footer text** — set from the task description -7. **Problems** — generate from the task config (template like `{a} × {b} + {c}`, variable ranges/sets, etc.) +7. **Problems** — generate directly from the `task` text in JSON config. Claude reads the free-text description and creates concrete math expressions ### Layout structure (do not change) - Page: `w-[210mm] h-[297mm]` white container -- Footer: absolute bottom, `h-[80mm]`, with white-to-transparent fade on top +- Footer: absolute bottom, `h-[80mm]`, with white-to-transparent fade on top. **No `overflow-hidden`** on footer container (causes 1px hairline artifact in PDF) - Footer bubble: absolute `bottom-[12mm]`, pill-shaped with semi-transparent white bg - Content area: `px-[12mm] pt-[8mm] pb-[65mm]` flex column - Header: hero image `w-[48%]` + title block centered @@ -135,7 +136,7 @@ This is the base visual design for all space-themed worksheets. When generating When generating HTML worksheets: -- **Always read** `src/templates/space-base.html` first and use it as the structural reference +- **Always read** `src/templates/space-base.html` (structure) and `src/examples/space-worksheet.html` (finished output) before generating - **Page size:** A4 = 210mm × 297mm - **CSS:** Uses Tailwind CDN in the HTML ` + + + + Исследуй Планету + + + + + + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ + 12 + 7 + 2 =   +
+
+ +
+
+ + 9 + 5 − 1 =   +
+
+ +
+
+ + 14 + 6 + 3 =   +
+
+ +
+
+ + 11 + 4 − 2 =   +
+
+ +
+
+ + 8 + 8 + 1 =   +
+
+ +
+
+ + 15 + 5 − 3 =   +
+
+ +
+
+ + 10 + 7 + 2 =   +
+
+ +
+
+ + 13 + 4 − 1 =   +
+
+ +
+
+ + 16 + 6 + 3 =   +
+
+ +
+
+ + 9 + 8 − 2 =   +
+
+ +
+
+ + 11 + 5 + 1 =   +
+
+ +
+
+ + 14 + 7 − 3 =   +
+
+ +
+
+ + 8 + 6 + 2 =   +
+
+ +
+
+ + 12 + 4 − 1 =   +
+
+ +
+
+ + 15 + 8 + 3 =   +
+
+ +
+
+ + 10 + 5 − 2 =   +
+
+ +
+
+ + 13 + 7 + 1 =   +
+
+ +
+
+ + 16 + 4 − 3 =   +
+
+ +
+
+ + 9 + 6 + 2 =   +
+
+ +
+
+ + 11 + 8 − 1 =   +
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ + 5 × 3 + 4 =   +
+
+ +
+
+ + 5 × 1 − 2 =   +
+
+ +
+
+ + 5 × 5 + 6 =   +
+
+ +
+
+ + 5 × 2 − 1 =   +
+
+ +
+
+ + 5 × 4 + 3 =   +
+
+ +
+
+ + 5 × 1 + 5 =   +
+
+ +
+
+ + 5 × 3 − 3 =   +
+
+ +
+
+ + 5 × 5 + 2 =   +
+
+ +
+
+ + 5 × 2 + 6 =   +
+
+ +
+
+ + 5 × 4 − 2 =   +
+
+ +
+
+ + 5 × 1 + 4 =   +
+
+ +
+
+ + 5 × 3 + 1 =   +
+
+ +
+
+ + 5 × 5 − 1 =   +
+
+ +
+
+ + 5 × 2 + 3 =   +
+
+ +
+
+ + 5 × 4 + 5 =   +
+
+ +
+
+ + 5 × 1 − 3 =   +
+
+ +
+
+ + 5 × 3 + 6 =   +
+
+ +
+
+ + 5 × 2 − 2 =   +
+
+ +
+
+ + 5 × 5 + 4 =   +
+
+ +
+
+ + 5 × 4 − 1 =   +
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ + 3 × 4 + 5 =   +
+
+ +
+
+ + 2 × 3 − 2 =   +
+
+ +
+
+ + 4 × 4 + 7 =   +
+
+ +
+
+ + 1 × 3 + 6 =   +
+
+ +
+
+ + 3 × 2 − 3 =   +
+
+ +
+
+ + 4 × 3 + 2 =   +
+
+ +
+
+ + 2 × 4 − 1 =   +
+
+ +
+
+ + 1 × 4 + 8 =   +
+
+ +
+
+ + 3 × 3 − 4 =   +
+
+ +
+
+ + 4 × 2 + 3 =   +
+
+ +
+
+ + 2 × 2 + 5 =   +
+
+ +
+
+ + 1 × 2 + 7 =   +
+
+ +
+
+ + 4 × 4 − 3 =   +
+
+ +
+
+ + 3 × 1 + 4 =   +
+
+ +
+
+ + 2 × 3 + 6 =   +
+
+ +
+
+ + 4 × 1 − 2 =   +
+
+ +
+
+ + 3 × 4 + 8 =   +
+
+ +
+
+ + 1 × 3 + 3 =   +
+
+ +
+
+ + 2 × 4 + 1 =   +
+
+ +
+
+ + 4 × 3 − 4 =   +
+
+ +
+
+
+ + + diff --git a/src/templates/space-base.html b/src/templates/space-base.html index f613e09..e761a97 100644 --- a/src/templates/space-base.html +++ b/src/templates/space-base.html @@ -29,7 +29,7 @@
-
+
diff --git a/tasks/space-exploration-1.json b/tasks/space-exploration-1.json new file mode 100644 index 0000000..9440da0 --- /dev/null +++ b/tasks/space-exploration-1.json @@ -0,0 +1,42 @@ +{ + "id": "space-exploration-1", + "title": "Исследуй Планету", + "description": "3-page space worksheet: addition ±, multiply by 5 ±, multiplication table ±", + "labels": { + "title": "Исследуй Планету", + "subtitle": "Собери ресурсы, решая примеры!", + "footerBubble": "Итого собрано на планете:" + }, + "theme": { + "style": "space", + "template": "space-base", + "icons": "assets/icons/pack1/" + }, + "layout": { + "columns": 2, + "problemsPerPage": 20 + }, + "pages": [ + { + "task": "A + B ± C, где A от 8 до 16, B от 4 до 8, C от 1 до 3. Знак ± выбирается случайно", + "problemCount": 20, + "heroImage": "assets/hero-images/spaceship2.jpeg", + "footerImage": "assets/footers/planet3.jpeg", + "heroDirection": "row-reverse" + }, + { + "task": "5 × N ± C, где N от 1 до 5, C от 1 до 6. Знак ± выбирается случайно", + "problemCount": 20, + "heroImage": "assets/hero-images/spaceship4.jpeg", + "footerImage": "assets/footers/planet5.jpeg", + "heroDirection": "row" + }, + { + "task": "A × B ± C, где A и B от 1 до 4, C от 1 до 8. Знак ± выбирается случайно", + "problemCount": 20, + "heroImage": "assets/hero-images/spaceship6.jpeg", + "footerImage": "assets/footers/planet1.jpeg", + "heroDirection": "row-reverse" + } + ] +}