refactor: new structure
This commit is contained in:
@@ -1,131 +0,0 @@
|
||||
{
|
||||
"id": "collecting-asteroids-1",
|
||||
"title": "Собери Астероиды",
|
||||
"description": "9-page asteroid-matching worksheet: match asteroids to cargo ships by weight sum, increasing difficulty",
|
||||
"labels": {
|
||||
"title": "Собери Астероиды",
|
||||
"subtitle": "Загрузи трюмы кораблей!",
|
||||
"footerBubble": "Итого загружено:"
|
||||
},
|
||||
"theme": {
|
||||
"style": "space-asteroids",
|
||||
"template": "space-base",
|
||||
"asteroids": "assets/icons/pack3-asteroids/"
|
||||
},
|
||||
"layout": {
|
||||
"type": "asteroid-matching",
|
||||
"shipsPerPage": 3,
|
||||
"asteroidTypesPerPage": 2,
|
||||
"asteroidTypeRatio": "70:30"
|
||||
},
|
||||
"pages": [
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 5, "fillCount": 2 },
|
||||
{ "capacity": 5, "fillCount": 2 },
|
||||
{ "capacity": 7, "fillCount": 3 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter1.png",
|
||||
"footerImage": "assets/footers/cabin1.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"cargoBays": ["cargo-bay1", "cargo-bay2", "cargo-bay3"],
|
||||
"asteroidTypes": ["asteroid1", "asteroid6"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 7, "fillCount": 3 },
|
||||
{ "capacity": 7, "fillCount": 3 },
|
||||
{ "capacity": 10, "fillCount": 4 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter2.png",
|
||||
"footerImage": "assets/footers/cabin2.jpeg",
|
||||
"heroDirection": "row",
|
||||
"cargoBays": ["cargo-bay4", "cargo-bay5", "cargo-bay6"],
|
||||
"asteroidTypes": ["asteroid3", "asteroid9"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 5, "fillCount": 2 },
|
||||
{ "capacity": 5, "fillCount": 3 },
|
||||
{ "capacity": 6, "fillCount": 3 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter3.png",
|
||||
"footerImage": "assets/footers/cabin3.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"cargoBays": ["cargo-bay7", "cargo-bay8", "cargo-bay9"],
|
||||
"asteroidTypes": ["asteroid5", "asteroid11"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 8, "fillCount": 2 },
|
||||
{ "capacity": 8, "fillCount": 3 },
|
||||
{ "capacity": 6, "fillCount": 2 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter4.png",
|
||||
"footerImage": "assets/footers/cabin4.jpeg",
|
||||
"heroDirection": "row",
|
||||
"cargoBays": ["cargo-bay1", "cargo-bay2", "cargo-bay3"],
|
||||
"asteroidTypes": ["asteroid2", "asteroid8"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 4, "fillCount": 1 },
|
||||
{ "capacity": 4, "fillCount": 2 },
|
||||
{ "capacity": 4, "fillCount": 3 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter5.png",
|
||||
"footerImage": "assets/footers/cabin5.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"cargoBays": ["cargo-bay4", "cargo-bay5", "cargo-bay6"],
|
||||
"asteroidTypes": ["asteroid4", "asteroid10"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 10, "fillCount": 4 },
|
||||
{ "capacity": 10, "fillCount": 3 },
|
||||
{ "capacity": 8, "fillCount": 3 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter6.png",
|
||||
"footerImage": "assets/footers/cabin6.jpeg",
|
||||
"heroDirection": "row",
|
||||
"cargoBays": ["cargo-bay7", "cargo-bay8", "cargo-bay9"],
|
||||
"asteroidTypes": ["asteroid7", "asteroid13"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 6, "fillCount": 2 },
|
||||
{ "capacity": 9, "fillCount": 3 },
|
||||
{ "capacity": 12, "fillCount": 4 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter7.png",
|
||||
"footerImage": "assets/footers/cabin7.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"cargoBays": ["cargo-bay1", "cargo-bay2", "cargo-bay3"],
|
||||
"asteroidTypes": ["asteroid12", "asteroid16"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 14, "fillCount": 3 },
|
||||
{ "capacity": 10, "fillCount": 2 },
|
||||
{ "capacity": 16, "fillCount": 4 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter8.png",
|
||||
"footerImage": "assets/footers/cabin8.jpeg",
|
||||
"heroDirection": "row",
|
||||
"cargoBays": ["cargo-bay4", "cargo-bay5", "cargo-bay6"],
|
||||
"asteroidTypes": ["asteroid14", "asteroid15"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 5, "fillCount": 2 },
|
||||
{ "capacity": 10, "fillCount": 4 },
|
||||
{ "capacity": 15, "fillCount": 5 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter9.png",
|
||||
"footerImage": "assets/footers/cabin9.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"cargoBays": ["cargo-bay7", "cargo-bay8", "cargo-bay9"],
|
||||
"asteroidTypes": ["asteroid1", "asteroid9"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
{
|
||||
"id": "collecting-asteroids-2",
|
||||
"title": "Собери Астероиды",
|
||||
"description": "9-page asteroid-matching worksheet v2: reshuffled assets, doubled difficulty",
|
||||
"labels": {
|
||||
"title": "Собери Астероиды",
|
||||
"subtitle": "Загрузи трюмы кораблей!",
|
||||
"footerBubble": "Итого загружено:"
|
||||
},
|
||||
"theme": {
|
||||
"style": "space-asteroids",
|
||||
"template": "space-base",
|
||||
"asteroids": "assets/icons/pack3-asteroids/"
|
||||
},
|
||||
"layout": {
|
||||
"type": "asteroid-matching",
|
||||
"shipsPerPage": 3,
|
||||
"asteroidTypesPerPage": 2,
|
||||
"asteroidTypeRatio": "70:30"
|
||||
},
|
||||
"pages": [
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 10, "fillCount": 2 },
|
||||
{ "capacity": 10, "fillCount": 2 },
|
||||
{ "capacity": 14, "fillCount": 3 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter5.png",
|
||||
"footerImage": "assets/footers/cabin7.jpeg",
|
||||
"heroDirection": "row",
|
||||
"cargoBays": ["cargo-bay4", "cargo-bay5", "cargo-bay6"],
|
||||
"asteroidTypes": ["asteroid7", "asteroid14"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 14, "fillCount": 3 },
|
||||
{ "capacity": 14, "fillCount": 3 },
|
||||
{ "capacity": 20, "fillCount": 4 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter2.png",
|
||||
"footerImage": "assets/footers/cabin4.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"cargoBays": ["cargo-bay7", "cargo-bay8", "cargo-bay9"],
|
||||
"asteroidTypes": ["asteroid4", "asteroid11"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 10, "fillCount": 2 },
|
||||
{ "capacity": 10, "fillCount": 3 },
|
||||
{ "capacity": 12, "fillCount": 3 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter8.png",
|
||||
"footerImage": "assets/footers/cabin1.jpeg",
|
||||
"heroDirection": "row",
|
||||
"cargoBays": ["cargo-bay1", "cargo-bay2", "cargo-bay3"],
|
||||
"asteroidTypes": ["asteroid10", "asteroid3"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 16, "fillCount": 2 },
|
||||
{ "capacity": 16, "fillCount": 3 },
|
||||
{ "capacity": 12, "fillCount": 2 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter3.png",
|
||||
"footerImage": "assets/footers/cabin9.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"cargoBays": ["cargo-bay4", "cargo-bay5", "cargo-bay6"],
|
||||
"asteroidTypes": ["asteroid16", "asteroid5"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 8, "fillCount": 1 },
|
||||
{ "capacity": 8, "fillCount": 2 },
|
||||
{ "capacity": 8, "fillCount": 3 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter9.png",
|
||||
"footerImage": "assets/footers/cabin2.jpeg",
|
||||
"heroDirection": "row",
|
||||
"cargoBays": ["cargo-bay7", "cargo-bay8", "cargo-bay9"],
|
||||
"asteroidTypes": ["asteroid2", "asteroid13"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 20, "fillCount": 4 },
|
||||
{ "capacity": 20, "fillCount": 3 },
|
||||
{ "capacity": 16, "fillCount": 3 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter1.png",
|
||||
"footerImage": "assets/footers/cabin6.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"cargoBays": ["cargo-bay1", "cargo-bay2", "cargo-bay3"],
|
||||
"asteroidTypes": ["asteroid8", "asteroid12"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 12, "fillCount": 2 },
|
||||
{ "capacity": 18, "fillCount": 3 },
|
||||
{ "capacity": 24, "fillCount": 4 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter6.png",
|
||||
"footerImage": "assets/footers/cabin3.jpeg",
|
||||
"heroDirection": "row",
|
||||
"cargoBays": ["cargo-bay4", "cargo-bay5", "cargo-bay6"],
|
||||
"asteroidTypes": ["asteroid15", "asteroid6"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 28, "fillCount": 3 },
|
||||
{ "capacity": 20, "fillCount": 2 },
|
||||
{ "capacity": 32, "fillCount": 4 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter4.png",
|
||||
"footerImage": "assets/footers/cabin8.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"cargoBays": ["cargo-bay7", "cargo-bay8", "cargo-bay9"],
|
||||
"asteroidTypes": ["asteroid9", "asteroid1"]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 10, "fillCount": 2 },
|
||||
{ "capacity": 20, "fillCount": 4 },
|
||||
{ "capacity": 30, "fillCount": 5 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter7.png",
|
||||
"footerImage": "assets/footers/cabin5.jpeg",
|
||||
"heroDirection": "row",
|
||||
"cargoBays": ["cargo-bay1", "cargo-bay2", "cargo-bay3"],
|
||||
"asteroidTypes": ["asteroid11", "asteroid4"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
{
|
||||
"id": "collecting-asteroids-3",
|
||||
"title": "Собери Астероиды",
|
||||
"description": "9-page asteroid-matching worksheet v3: reshuffled assets, halved asteroid values",
|
||||
"labels": {
|
||||
"title": "Собери Астероиды",
|
||||
"subtitle": "Загрузи трюмы кораблей!",
|
||||
"footerBubble": "Итого загружено:"
|
||||
},
|
||||
"theme": {
|
||||
"style": "space-asteroids",
|
||||
"template": "space-base",
|
||||
"asteroids": "assets/icons/pack3-asteroids/"
|
||||
},
|
||||
"layout": {
|
||||
"type": "asteroid-matching",
|
||||
"shipsPerPage": 3,
|
||||
"asteroidTypesPerPage": 2,
|
||||
"asteroidTypeRatio": "70:30"
|
||||
},
|
||||
"pages": [
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 11, "fillCount": 2 },
|
||||
{ "capacity": 9, "fillCount": 2 },
|
||||
{ "capacity": 13, "fillCount": 6 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter4.png",
|
||||
"footerImage": "assets/footers/cabin3.jpeg",
|
||||
"heroDirection": "row",
|
||||
"cargoBays": ["cargo-bay7", "cargo-bay8", "cargo-bay9"],
|
||||
"asteroidTypes": ["asteroid3", "asteroid10"],
|
||||
"asteroidValues": [3, 2, 1, 4, 5, 2, 3, 6, 5, 4, 1, 6]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 12, "fillCount": 3 },
|
||||
{ "capacity": 12, "fillCount": 3 },
|
||||
{ "capacity": 18, "fillCount": 4 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter7.png",
|
||||
"footerImage": "assets/footers/cabin6.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"cargoBays": ["cargo-bay1", "cargo-bay2", "cargo-bay3"],
|
||||
"asteroidTypes": ["asteroid6", "asteroid13"],
|
||||
"asteroidValues": [4, 5, 3, 6, 2, 7, 4, 3, 5, 2, 6, 4]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 9, "fillCount": 5 },
|
||||
{ "capacity": 11, "fillCount": 3 },
|
||||
{ "capacity": 11, "fillCount": 2 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter1.png",
|
||||
"footerImage": "assets/footers/cabin9.jpeg",
|
||||
"heroDirection": "row",
|
||||
"cargoBays": ["cargo-bay4", "cargo-bay5", "cargo-bay6"],
|
||||
"asteroidTypes": ["asteroid2", "asteroid8"],
|
||||
"asteroidValues": [2, 4, 1, 3, 5, 2, 1, 3, 4, 6, 5, 2]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 15, "fillCount": 4 },
|
||||
{ "capacity": 17, "fillCount": 5 },
|
||||
{ "capacity": 11, "fillCount": 2 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter6.png",
|
||||
"footerImage": "assets/footers/cabin2.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"cargoBays": ["cargo-bay7", "cargo-bay8", "cargo-bay9"],
|
||||
"asteroidTypes": ["asteroid12", "asteroid15"],
|
||||
"asteroidValues": [4, 3, 5, 2, 6, 1, 3, 4, 6, 2, 5, 4]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 7, "fillCount": 2 },
|
||||
{ "capacity": 9, "fillCount": 4 },
|
||||
{ "capacity": 7, "fillCount": 2 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter2.png",
|
||||
"footerImage": "assets/footers/cabin5.jpeg",
|
||||
"heroDirection": "row",
|
||||
"cargoBays": ["cargo-bay1", "cargo-bay2", "cargo-bay3"],
|
||||
"asteroidTypes": ["asteroid1", "asteroid9"],
|
||||
"asteroidValues": [3, 1, 4, 2, 5, 1, 6, 2, 3, 4, 5]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 18, "fillCount": 4 },
|
||||
{ "capacity": 18, "fillCount": 5 },
|
||||
{ "capacity": 14, "fillCount": 3 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter8.png",
|
||||
"footerImage": "assets/footers/cabin7.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"cargoBays": ["cargo-bay4", "cargo-bay5", "cargo-bay6"],
|
||||
"asteroidTypes": ["asteroid5", "asteroid16"],
|
||||
"asteroidValues": [3, 4, 5, 6, 2, 4, 7, 3, 2, 5, 6, 4, 3, 7]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 10, "fillCount": 2 },
|
||||
{ "capacity": 16, "fillCount": 3 },
|
||||
{ "capacity": 22, "fillCount": 6 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter9.png",
|
||||
"footerImage": "assets/footers/cabin4.jpeg",
|
||||
"heroDirection": "row",
|
||||
"cargoBays": ["cargo-bay7", "cargo-bay8", "cargo-bay9"],
|
||||
"asteroidTypes": ["asteroid11", "asteroid7"],
|
||||
"asteroidValues": [4, 3, 2, 6, 5, 3, 7, 4, 5, 2, 6, 4]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 26, "fillCount": 0 },
|
||||
{ "capacity": 18, "fillCount": 0 },
|
||||
{ "capacity": 30, "fillCount": 0 }
|
||||
],
|
||||
"_unsolvable": true,
|
||||
"heroImage": "assets/hero-images/splitters/splitter5.png",
|
||||
"footerImage": "assets/footers/cabin1.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"cargoBays": ["cargo-bay1", "cargo-bay2", "cargo-bay3"],
|
||||
"asteroidTypes": ["asteroid14", "asteroid4"],
|
||||
"asteroidValues": [6, 4, 5, 3, 7, 2, 4, 6, 5, 7, 3, 4, 6]
|
||||
},
|
||||
{
|
||||
"ships": [
|
||||
{ "capacity": 8, "fillCount": 2 },
|
||||
{ "capacity": 18, "fillCount": 3 },
|
||||
{ "capacity": 28, "fillCount": 8 }
|
||||
],
|
||||
"heroImage": "assets/hero-images/splitters/splitter3.png",
|
||||
"footerImage": "assets/footers/cabin8.jpeg",
|
||||
"heroDirection": "row",
|
||||
"cargoBays": ["cargo-bay4", "cargo-bay5", "cargo-bay6"],
|
||||
"asteroidTypes": ["asteroid10", "asteroid6"],
|
||||
"asteroidValues": [4, 3, 2, 5, 6, 3, 4, 7, 2, 5, 4, 6, 3, 7, 5]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
# Collecting Asteroids Task Type
|
||||
|
||||
Match asteroids to cargo ships by weight sum. Each page has 3 ships with cargo bays and ~12 asteroids scattered across the page. Child draws lines connecting asteroids to ships so that asteroid values sum to ship capacity.
|
||||
|
||||
## Layout
|
||||
|
||||
- 3 ships per page with cargo bay images
|
||||
- 2 asteroid types per page (70:30 ratio distribution)
|
||||
- 12 asteroids per page scattered with absolute positioning
|
||||
- Hero images: splitter ships from `assets/hero-images/splitters/`
|
||||
- Footer images: cabin interiors from `assets/footers/cabin{1-9}.jpeg`
|
||||
- Cargo bay images: `assets/icons/pack4-cargobay/cargo-bay{1-9}.png`
|
||||
- Asteroid images: `assets/icons/pack3-asteroids/asteroid{1-16}.png`
|
||||
|
||||
## Asteroid Placement Rules
|
||||
|
||||
- Distribute asteroids evenly across the page area using grid-based approach
|
||||
- Asteroids must not overlap with ships or cargo bays
|
||||
- Each asteroid has a numeric value (1-20) displayed on it
|
||||
- Scale formula: `scale = baseScale + 0.15 * value` (default baseScale: 0.30)
|
||||
- No editor-first approach — generate everything via AI first, editor comes later for fine-tuning
|
||||
|
||||
## Validation
|
||||
|
||||
Use verify script to check that asteroid values can be partitioned to ship capacities:
|
||||
```bash
|
||||
node scripts/verify.mjs --ships 10,10,14 --asteroids 3,2,1,4,5,2,3,6,5,4,1,6
|
||||
```
|
||||
|
||||
Always verify solvability after generating or editing asteroid values.
|
||||
|
||||
## Scripts
|
||||
|
||||
- `scripts/verify.mjs` — solver to verify asteroid-to-ship partition (stdout → Claude reads)
|
||||
- `scripts/transform-collecting3.mjs` — bulk asset replacement utility
|
||||
|
||||
## Editor
|
||||
|
||||
`editor.html?file={docId}` — drag asteroids and ship circles, adjust values and scales.
|
||||
|
||||
Key controls:
|
||||
- Drag: move asteroid/ship position
|
||||
- `+/-`: change asteroid value (1-20 range)
|
||||
- `[/]`: rotate ±5° (Shift = ±1°)
|
||||
- `</.>`: adjust base scale per asteroid type
|
||||
- Save: writes to `docs/{docId}.data.json`
|
||||
@@ -0,0 +1,66 @@
|
||||
# Collecting Asteroids 1
|
||||
|
||||
**Title:** Собери Астероиды
|
||||
**Subtitle:** Загрузи трюмы кораблей!
|
||||
**Footer bubble:** Итого загружено:
|
||||
|
||||
## Layout
|
||||
|
||||
- 3 ships per page, 2 asteroid types per page (70:30 ratio)
|
||||
- Asteroids: assets/icons/pack3-asteroids/
|
||||
|
||||
## Pages
|
||||
|
||||
### Page 1
|
||||
- **Ships:** capacity 5 (fill 2), capacity 5 (fill 2), capacity 7 (fill 3)
|
||||
- **Hero:** splitter1.png, direction: row-reverse
|
||||
- **Cargo bays:** cargo-bay1, cargo-bay2, cargo-bay3
|
||||
- **Asteroid types:** asteroid1, asteroid6
|
||||
|
||||
### Page 2
|
||||
- **Ships:** capacity 7 (fill 3), capacity 7 (fill 3), capacity 10 (fill 4)
|
||||
- **Hero:** splitter2.png, direction: row
|
||||
- **Cargo bays:** cargo-bay4, cargo-bay5, cargo-bay6
|
||||
- **Asteroid types:** asteroid3, asteroid9
|
||||
|
||||
### Page 3
|
||||
- **Ships:** capacity 5 (fill 2), capacity 5 (fill 3), capacity 6 (fill 3)
|
||||
- **Hero:** splitter3.png, direction: row-reverse
|
||||
- **Cargo bays:** cargo-bay7, cargo-bay8, cargo-bay9
|
||||
- **Asteroid types:** asteroid5, asteroid11
|
||||
|
||||
### Page 4
|
||||
- **Ships:** capacity 8 (fill 2), capacity 8 (fill 3), capacity 6 (fill 2)
|
||||
- **Hero:** splitter4.png, direction: row
|
||||
- **Cargo bays:** cargo-bay1, cargo-bay2, cargo-bay3
|
||||
- **Asteroid types:** asteroid2, asteroid8
|
||||
|
||||
### Page 5
|
||||
- **Ships:** capacity 4 (fill 1), capacity 4 (fill 2), capacity 4 (fill 3)
|
||||
- **Hero:** splitter5.png, direction: row-reverse
|
||||
- **Cargo bays:** cargo-bay4, cargo-bay5, cargo-bay6
|
||||
- **Asteroid types:** asteroid4, asteroid10
|
||||
|
||||
### Page 6
|
||||
- **Ships:** capacity 10 (fill 4), capacity 10 (fill 3), capacity 8 (fill 3)
|
||||
- **Hero:** splitter6.png, direction: row
|
||||
- **Cargo bays:** cargo-bay7, cargo-bay8, cargo-bay9
|
||||
- **Asteroid types:** asteroid7, asteroid13
|
||||
|
||||
### Page 7
|
||||
- **Ships:** capacity 6 (fill 2), capacity 9 (fill 3), capacity 12 (fill 4)
|
||||
- **Hero:** splitter7.png, direction: row-reverse
|
||||
- **Cargo bays:** cargo-bay1, cargo-bay2, cargo-bay3
|
||||
- **Asteroid types:** asteroid12, asteroid16
|
||||
|
||||
### Page 8
|
||||
- **Ships:** capacity 14 (fill 3), capacity 10 (fill 2), capacity 16 (fill 4)
|
||||
- **Hero:** splitter8.png, direction: row
|
||||
- **Cargo bays:** cargo-bay4, cargo-bay5, cargo-bay6
|
||||
- **Asteroid types:** asteroid14, asteroid15
|
||||
|
||||
### Page 9
|
||||
- **Ships:** capacity 5 (fill 2), capacity 10 (fill 4), capacity 15 (fill 5)
|
||||
- **Hero:** splitter9.png, direction: row-reverse
|
||||
- **Cargo bays:** cargo-bay7, cargo-bay8, cargo-bay9
|
||||
- **Asteroid types:** asteroid1, asteroid9
|
||||
@@ -0,0 +1,348 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<title>Собери Астероиды</title>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: { nunito: ['Nunito', 'sans-serif'] },
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@page { size: A4; margin: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-200 font-nunito">
|
||||
|
||||
<!-- PAGE 1: ships 5(2), 5(2), 7(3) — L-R-L -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin1.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/splitters/splitter1.png" class="w-[66%] shrink-0 object-contain" style="transform: scaleX(-1);" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: -82mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay1.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay2.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">5</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay3.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">7</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 67mm; top: 1mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 111mm; top: 15mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 146mm; top: 28mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(1.12);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 22mm; top: 55mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(12deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 57mm; top: 43mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(-20deg) scale(1.08);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 93mm; top: 49mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 80mm; top: 87mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(25deg) scale(0.95);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 33mm; top: 87mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(-5deg) scale(1.02);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 115mm; top: 132mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.10);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 45mm; top: 125mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(0.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 79mm; top: 141mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(8deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 132mm; top: 160mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(-10deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 2: ships 7(3), 7(3), 10(4) — R-L-R -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin2.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<img src="../../assets/hero-images/splitters/splitter2.png" class="w-[66%] shrink-0 object-contain" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: 120mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay4.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">7</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay5.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">7</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay6.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">10</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 15mm; top: 5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 42mm; top: 37mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(1.08);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 96mm; top: 2mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 86mm; top: 46mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 44mm; top: -5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 140mm; top: 77mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(1.12);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 96mm; top: 88mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(20deg) scale(0.95);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 56mm; top: 73mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(-25deg) scale(1.10);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 8mm; top: 154mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(5deg) scale(0.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 6mm; top: 39mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(12deg) scale(1.02);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 70mm; top: 106mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 31mm; top: 120mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 83mm; top: 154mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 3: ships 5(2), 5(3), 6(3) — L-R-L -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin3.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/splitters/splitter3.png" class="w-[66%] shrink-0 object-contain" style="transform: scaleX(-1);" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: -82mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay7.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay8.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">5</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay9.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">6</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 80mm; top: 5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(-20deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 118mm; top: 5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 158mm; top: 22mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(1.12);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 11mm; top: 73mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 72mm; top: 49mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(1.08);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 103mm; top: 37mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 47mm; top: 81mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(25deg) scale(0.95);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 82mm; top: 99mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(1.02);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 117mm; top: 127mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.10);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 52mm; top: 134mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(8deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 69mm; top: 157mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(0.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 162mm; top: 144mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(12deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 4: ships 8(2), 8(3), 6(2) — R-L-R -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin4.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<img src="../../assets/hero-images/splitters/splitter4.png" class="w-[66%] shrink-0 object-contain" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: 120mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay1.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">8</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay2.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay3.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">6</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: -2mm; top: 13mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 36mm; top: 22mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 77mm; top: 25mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(8deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 75mm; top: 60mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(1.12);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 112mm; top: 49mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(12deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 110mm; top: -5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(-5deg) scale(1.08);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 40mm; top: 78mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.95);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 55mm; top: 113mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(0.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 82mm; top: 107mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(1.10);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 14mm; top: 122mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(20deg) scale(1.02);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 139mm; top: 76mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 74mm; top: 145mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 5: ships 4(1), 4(2), 4(3) — L-R-L -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin5.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/splitters/splitter5.png" class="w-[66%] shrink-0 object-contain" style="transform: scaleX(-1);" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: -82mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay4.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay5.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">4</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay6.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">4</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 50mm; top: 0mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(-20deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 119mm; top: 6mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 162mm; top: 18mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(1.12);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: -3mm; top: 71mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 54mm; top: 42mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(1.08);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 90mm; top: 29mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 46mm; top: 82mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(25deg) scale(0.95);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 85mm; top: 90mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(1.02);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 149mm; top: 126mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.10);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 68mm; top: 129mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(0.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 101mm; top: 148mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(8deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 6: ships 10(4), 10(3), 8(3) — R-L-R -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin6.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<img src="../../assets/hero-images/splitters/splitter6.png" class="w-[66%] shrink-0 object-contain" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: 120mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay7.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">10</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay8.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay9.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">8</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: -3mm; top: 22mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 48mm; top: 8mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid13.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(1.08);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 97mm; top: 6mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 31mm; top: 40mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 77mm; top: 34mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid13.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 102mm; top: 66mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(1.12);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 154mm; top: 82mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(20deg) scale(0.95);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 68mm; top: 84mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid13.png" class="w-full h-full object-contain" style="transform: rotate(-25deg) scale(1.10);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 57mm; top: 114mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(5deg) scale(0.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 122mm; top: 88mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(12deg) scale(1.02);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 1mm; top: 157mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid13.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 34mm; top: 133mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 89mm; top: 122mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 82mm; top: 145mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(8deg) scale(1.00);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 7: ships 6(2), 9(3), 12(4) — L-R-L -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin7.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/splitters/splitter7.png" class="w-[66%] shrink-0 object-contain" style="transform: scaleX(-1);" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: -82mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay1.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay2.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">9</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay3.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">12</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 59mm; top: -1mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 116mm; top: 12mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 151mm; top: 18mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(1.12);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 8mm; top: 74mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(12deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 55mm; top: 45mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(-20deg) scale(1.08);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 90mm; top: 44mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 64mm; top: 79mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(25deg) scale(0.95);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 94mm; top: 99mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(-5deg) scale(1.02);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 147mm; top: 133mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.10);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 35mm; top: 96mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(0.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 71mm; top: 127mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(8deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 112mm; top: 148mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(-10deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 8: ships 14(3), 10(2), 16(4) — R-L-R -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin8.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<img src="../../assets/hero-images/splitters/splitter8.png" class="w-[66%] shrink-0 object-contain" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: 120mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay4.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">14</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay5.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay6.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">16</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: -6mm; top: 4mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 8mm; top: 30mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(1.08);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 49mm; top: 11mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 63mm; top: 44mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 101mm; top: -3mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 168mm; top: 68mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(1.12);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 119mm; top: 79mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(20deg) scale(0.95);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 59mm; top: 78mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(-25deg) scale(1.10);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 90mm; top: 98mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(5deg) scale(0.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 70mm; top: 128mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(12deg) scale(1.02);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: -2mm; top: 130mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 32mm; top: 144mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 88mm; top: 158mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 9: ships 5(2), 10(4), 15(5) — L-R-L -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin9.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/splitters/splitter9.png" class="w-[66%] shrink-0 object-contain" style="transform: scaleX(-1);" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: -82mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay7.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay8.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">10</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay9.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">15</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 31mm; top: -2mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(-20deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 132mm; top: 5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 162mm; top: 13mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(1.12);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 89mm; top: 7mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 39mm; top: 59mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(1.08);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 68mm; top: 39mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 115mm; top: 35mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(25deg) scale(0.95);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 1mm; top: 91mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(1.02);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 77mm; top: 71mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.10);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 85mm; top: 114mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(-5deg) scale(0.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 131mm; top: 129mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(12deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 52mm; top: 110mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 63mm; top: 155mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(8deg) scale(0.95);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 103mm; top: 143mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(20deg) scale(1.00);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 146mm; top: 157mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,35 @@
|
||||
# Collecting Asteroids 2
|
||||
|
||||
**Title:** Собери Астероиды
|
||||
**Subtitle:** Загрузи трюмы кораблей!
|
||||
**Footer bubble:** Итого загружено:
|
||||
|
||||
## Notes
|
||||
|
||||
v2: reshuffled assets, doubled difficulty compared to v1.
|
||||
|
||||
## Layout
|
||||
|
||||
- 3 ships per page, 2 asteroid types per page (70:30 ratio)
|
||||
- Asteroids: assets/icons/pack3-asteroids/
|
||||
- Uses different splitters, cabins, cargo bays and asteroid types than v1
|
||||
|
||||
## Pages
|
||||
|
||||
### Page 1
|
||||
- **Ships:** capacity 10 (fill 2), capacity 10 (fill 2), capacity 14 (fill 3)
|
||||
- **Hero:** splitter5.png, direction: row
|
||||
- **Cargo bays:** cargo-bay4, cargo-bay5, cargo-bay6
|
||||
- **Asteroid types:** asteroid7, asteroid14
|
||||
|
||||
### Page 2
|
||||
- **Ships:** capacity 14 (fill 3), capacity 14 (fill 3), capacity 20 (fill 4)
|
||||
- **Hero:** splitter2.png, direction: row-reverse
|
||||
- **Cargo bays:** cargo-bay7, cargo-bay8, cargo-bay9
|
||||
- **Asteroid types:** asteroid4, asteroid11
|
||||
|
||||
### Page 3
|
||||
- **Ships:** capacity 10 (fill 2), capacity 10 (fill 3), capacity 12 (fill 3)
|
||||
- **Hero:** splitter8.png, direction: row
|
||||
- **Cargo bays:** cargo-bay1, cargo-bay2, cargo-bay3
|
||||
- **Asteroid types:** asteroid2, asteroid9
|
||||
@@ -0,0 +1,347 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<title>Собери Астероиды</title>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: { nunito: ['Nunito', 'sans-serif'] },
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@page { size: A4; margin: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-200 font-nunito">
|
||||
|
||||
<!-- PAGE 1: ships 10(2), 10(2), 14(3) — R-L-R -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin7.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<img src="../../assets/hero-images/splitters/splitter5.png" class="w-[66%] shrink-0 object-contain" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: 120mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay4.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">10</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay5.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay6.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">14</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 4mm; top: 6mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(33deg) scale(1.50);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 91mm; top: 18mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(0.68);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 65mm; top: -5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(23deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 14mm; top: 28mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 58mm; top: 59mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(1.12);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 160mm; top: 74mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(1.35);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 53mm; top: 107mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(1.57);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 101mm; top: 76mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(1.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
<div class="absolute" style="left: 62mm; top: 134mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(0deg) scale(1.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 24mm; top: 117mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(1.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 40mm; top: 156mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(-80deg) scale(0.62);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 3mm; top: 129mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(7deg) scale(2.00);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 2: ships 14(3), 14(3), 20(4) — L-R-L -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin4.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/splitters/splitter2.png" class="w-[66%] shrink-0 object-contain" style="transform: scaleX(-1);" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: -82mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay7.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">14</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay8.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">14</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay9.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">20</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 60mm; top: -3mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(20deg) scale(0.95);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 105mm; top: 10mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(1.08);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 150mm; top: 19mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.73);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 22mm; top: 0mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(-63deg) scale(1.12);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 85mm; top: 82mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.67);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 80mm; top: 50mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(-25deg) scale(1.50);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
<div class="absolute" style="left: 161mm; top: 124mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(95deg) scale(1.00);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 44mm; top: 75mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: -5mm; top: 87mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(0.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 101mm; top: 157mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(12deg) scale(0.62);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 73mm; top: 120mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(1.42);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 140mm; top: 150mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 3: ships 10(2), 10(3), 12(3) — R-L-R -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin1.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<img src="../../assets/hero-images/splitters/splitter8.png" class="w-[66%] shrink-0 object-contain" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: 120mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay1.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">10</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay2.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay3.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">12</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 37mm; top: 7mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(0.83);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 78mm; top: 12mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 109mm; top: -5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(0.47);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 0mm; top: 31mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.97);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 60mm; top: 59mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(-20deg) scale(1.40);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 102mm; top: 42mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 132mm; top: 71mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(25deg) scale(0.50);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 2mm; top: 128mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(1.02);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 67mm; top: 98mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(3deg) scale(1.35);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 81mm; top: 147mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(-25deg) scale(1.65);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
<div class="absolute" style="left: 36mm; top: 160mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(12deg) scale(1.45);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 109mm; top: 85mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(8deg) scale(0.77);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 4: ships 16(2), 16(3), 12(2) — L-R-L -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin9.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/splitters/splitter3.png" class="w-[66%] shrink-0 object-contain" style="transform: scaleX(-1);" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: -82mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay4.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">16</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay5.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">16</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay6.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">12</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 71mm; top: 3mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(12deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 66mm; top: 86mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(1.08);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 160mm; top: 28mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(8deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: -10mm; top: 72mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(0.72);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 63mm; top: 42mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(20deg) scale(1.82);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
<div class="absolute" style="left: 76mm; top: 73mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(-5deg) scale(0.40);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 149mm; top: 132mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 22mm; top: 82mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(1.35);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 125mm; top: 7mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(1.40);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
<div class="absolute" style="left: 103mm; top: 120mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(-10deg) scale(0.57);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 67mm; top: 128mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(1.47);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 103mm; top: 155mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 5: ships 8(1), 8(2), 8(3) — R-L-R -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin2.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<img src="../../assets/hero-images/splitters/splitter9.png" class="w-[66%] shrink-0 object-contain" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: 120mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay7.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">8</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay8.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay9.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">8</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 45mm; top: 5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 83mm; top: 16mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid13.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(0.53);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 27mm; top: 160mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(37deg) scale(1.12);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: -1mm; top: 30mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 66mm; top: 51mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid13.png" class="w-full h-full object-contain" style="transform: rotate(-20deg) scale(1.58);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 108mm; top: 65mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 7mm; top: 126mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(75deg) scale(1.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
<div class="absolute" style="left: 73mm; top: 102mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid13.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(0.72);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 140mm; top: 86mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(1.10);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 0mm; top: 6mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(0.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 83mm; top: 155mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(8deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 6: ships 20(4), 20(3), 16(3) — L-R-L -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin6.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/splitters/splitter1.png" class="w-[66%] shrink-0 object-contain" style="transform: scaleX(-1);" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: -82mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay1.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">20</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay2.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">20</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay3.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">16</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 79mm; top: 24mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(65deg) scale(0.67);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 66mm; top: -5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(1.08);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 148mm; top: 18mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(73deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 99mm; top: 135mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(-42deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 47mm; top: 59mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(20deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 84mm; top: 48mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(40deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 114mm; top: 21mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(53deg) scale(1.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
<div class="absolute" style="left: 16mm; top: 74mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 65mm; top: 82mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.50);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 84mm; top: 82mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(1.17);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 146mm; top: 157mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(1.82);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 60mm; top: 108mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 81mm; top: 113mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(0.68);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 80mm; top: 160mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(1.78);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 7: ships 12(2), 18(3), 24(4) — R-L-R -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin3.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<img src="../../assets/hero-images/splitters/splitter6.png" class="w-[66%] shrink-0 object-contain" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: 120mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay4.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">12</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay5.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">18</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay6.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">24</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 37mm; top: 4mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(-10deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 78mm; top: -3mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(17deg) scale(0.68);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 112mm; top: -1mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(50deg) scale(0.62);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 2mm; top: 13mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 68mm; top: 58mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(1.08);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 99mm; top: 45mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(-5deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 66mm; top: 98mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(-55deg) scale(1.50);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
<div class="absolute" style="left: 88mm; top: 78mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(0.87);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 123mm; top: 81mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.10);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: -10mm; top: 136mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(0.65);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 50mm; top: 128mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(5deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 84mm; top: 160mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(-118deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 8: ships 28(3), 20(2), 32(4) — L-R-L -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin8.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/splitters/splitter4.png" class="w-[66%] shrink-0 object-contain" style="transform: scaleX(-1);" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: -82mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay7.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">28</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay8.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">20</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay9.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">32</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 72mm; top: 13mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(-13deg) scale(1.80);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 166mm; top: -1mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(0.83);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 47mm; top: -5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(-43deg) scale(1.67);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 101mm; top: 16mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(3deg) scale(1.15);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 42mm; top: 52mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(1.48);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
<div class="absolute" style="left: 79mm; top: 60mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(0.87);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 91mm; top: 43mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(-5deg) scale(1.45);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 6mm; top: 82mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(-25deg) scale(1.10);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 68mm; top: 87mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(0deg) scale(1.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 93mm; top: 91mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(3deg) scale(2.00);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
<div class="absolute" style="left: 137mm; top: 133mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(0.62);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 74mm; top: 125mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(5deg) scale(1.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 95mm; top: 146mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(-7deg) scale(1.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 9: ships 10(2), 20(4), 30(5) — R-L-R -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin5.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<img src="../../assets/hero-images/splitters/splitter7.png" class="w-[66%] shrink-0 object-contain" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: 120mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay1.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">10</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay2.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">20</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay3.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">30</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 53mm; top: 1mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-20deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 97mm; top: 9mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 129mm; top: -5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(0.47);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 3mm; top: 16mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.92);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 74mm; top: 36mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(1.08);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 41mm; top: 40mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 130mm; top: 56mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(25deg) scale(0.95);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 61mm; top: 91mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(1.72);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
<div class="absolute" style="left: 93mm; top: 63mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(0.50);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 164mm; top: 86mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-5deg) scale(1.15);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: -5mm; top: 123mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(12deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 71mm; top: 138mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(1.42);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 114mm; top: 96mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(8deg) scale(0.65);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 19mm; top: 155mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(20deg) scale(1.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
<div class="absolute" style="left: 112mm; top: 158mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(0.88);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
# Collecting Asteroids 3
|
||||
|
||||
**Title:** Собери Астероиды
|
||||
**Subtitle:** Загрузи трюмы кораблей!
|
||||
**Footer bubble:** Итого загружено:
|
||||
|
||||
## Notes
|
||||
|
||||
v3: reshuffled assets, halved asteroid values. Includes explicit asteroidValues per page.
|
||||
|
||||
## Layout
|
||||
|
||||
- 3 ships per page, 2 asteroid types per page (70:30 ratio)
|
||||
- Asteroids: assets/icons/pack3-asteroids/
|
||||
|
||||
## Pages
|
||||
|
||||
### Page 1
|
||||
- **Ships:** capacity 11 (fill 2), capacity 9 (fill 2), capacity 13 (fill 6)
|
||||
- **Hero:** splitter4.png, direction: row
|
||||
- **Cargo bays:** cargo-bay7, cargo-bay8, cargo-bay9
|
||||
- **Asteroid types:** asteroid3, asteroid10
|
||||
- **Asteroid values:** 3, 2, 1, 4, 5, 2, 3, 6, 5, 4, 1, 6
|
||||
|
||||
### Page 2
|
||||
- **Ships:** capacity 12 (fill 3), capacity 12 (fill 3), capacity 18 (fill 4)
|
||||
- **Hero:** splitter7.png, direction: row-reverse
|
||||
- **Cargo bays:** cargo-bay1, cargo-bay2, cargo-bay3
|
||||
- **Asteroid types:** asteroid6, asteroid13
|
||||
- **Asteroid values:** 4, 5, 3, 6, 2, 7, 4, 3, 5, 2, 6, 4
|
||||
|
||||
### Page 3
|
||||
- **Ships:** capacity 9 (fill 5), capacity 9 (fill 5), capacity 11 (fill 2)
|
||||
- **Hero:** splitter1.png, direction: row
|
||||
- **Cargo bays:** cargo-bay4, cargo-bay5, cargo-bay6
|
||||
- **Asteroid types:** asteroid1, asteroid8
|
||||
@@ -0,0 +1,347 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<title>Собери Астероиды</title>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: { nunito: ['Nunito', 'sans-serif'] },
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@page { size: A4; margin: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-200 font-nunito">
|
||||
|
||||
<!-- PAGE 1: ships 11(2), 9(2), 13(6) — R-L-R -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin3.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<img src="../../assets/hero-images/splitters/splitter4.png" class="w-[66%] shrink-0 object-contain" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: 120mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay7.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 28%; top: 54%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">10</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay8.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 72%; top: 44%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">11</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay9.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 26%; top: 46%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">12</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 149mm; top: 78mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(33deg) scale(0.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 81mm; top: 26mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 64mm; top: 52mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(23deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 14mm; top: 28mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 50mm; top: 9mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 87mm; top: -2mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 82mm; top: 105mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 93mm; top: 60mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 66mm; top: 142mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(0deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 129mm; top: -5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 45mm; top: 117mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(-80deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 6mm; top: 123mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid3.png" class="w-full h-full object-contain" style="transform: rotate(7deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 2: ships 12(3), 12(3), 18(4) — L-R-L -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin6.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/splitters/splitter7.png" class="w-[66%] shrink-0 object-contain" style="transform: scaleX(-1);" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: -82mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay1.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 62%; top: 40%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">12</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay2.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 28%; top: 39%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">12</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay3.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 73%; top: 51%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">18</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 72mm; top: -5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(20deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 105mm; top: 10mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid13.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 150mm; top: 19mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 52mm; top: 30mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(-63deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 85mm; top: 82mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid13.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 86mm; top: 51mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(-25deg) scale(1.35);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">7</span></div></div></div>
|
||||
<div class="absolute" style="left: 164mm; top: 127mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(95deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 44mm; top: 75mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid13.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: -5mm; top: 87mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 108mm; top: 152mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(12deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 73mm; top: 120mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid13.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 136mm; top: 154mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 3: ships 9(5), 11(3), 11(2) — R-L-R -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin9.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<img src="../../assets/hero-images/splitters/splitter1.png" class="w-[66%] shrink-0 object-contain" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: 120mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay4.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 28%; top: 34%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">7</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay5.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 75%; top: 47%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay6.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 22%; top: 39%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">6</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 38mm; top: 8mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(-13deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 76mm; top: 10mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(1.50);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 109mm; top: -5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(0.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: -4mm; top: 25mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(1.65);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">9</span></div></div></div>
|
||||
<div class="absolute" style="left: 64mm; top: 56mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(-20deg) scale(1.80);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 97mm; top: 49mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 175mm; top: 78mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(25deg) scale(2.10);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
<div class="absolute" style="left: -10mm; top: 124mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 48mm; top: 113mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(3deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 65mm; top: 151mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(-25deg) scale(1.80);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 18mm; top: 144mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid8.png" class="w-full h-full object-contain" style="transform: rotate(17deg) scale(1.50);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 106mm; top: 86mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid2.png" class="w-full h-full object-contain" style="transform: rotate(13deg) scale(0.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 4: ships 15(4), 17(5), 11(2) — L-R-L -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin2.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/splitters/splitter6.png" class="w-[66%] shrink-0 object-contain" style="transform: scaleX(-1);" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: -82mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay7.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 71%; top: 55%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">15</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay8.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 28%; top: 43%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">10</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay9.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 76%; top: 49%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">25</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 64mm; top: 2mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(-68deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 58mm; top: 88mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(0.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 160mm; top: 28mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(8deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: -10mm; top: 76mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 63mm; top: 42mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(20deg) scale(0.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 82mm; top: 71mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(-5deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 149mm; top: 132mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 22mm; top: 82mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 121mm; top: 7mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 103mm; top: 120mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(-10deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 62mm; top: 130mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid15.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 103mm; top: 155mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid12.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 5: ships 7(2), 9(4), 7(2) — R-L-R -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin5.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<img src="../../assets/hero-images/splitters/splitter2.png" class="w-[66%] shrink-0 object-contain" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: 120mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay1.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 37%; top: 38%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">13</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay2.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 71%; top: 41%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">11</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay3.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 23%; top: 47%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">15</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 45mm; top: 5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 64mm; top: 62mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(3deg) scale(0.85);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 27mm; top: 160mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(37deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: -1mm; top: 32mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 82mm; top: 16mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(-20deg) scale(1.15);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 108mm; top: 65mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 7mm; top: 126mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(75deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 71mm; top: 104mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid9.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(1.45);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 145mm; top: 86mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 3mm; top: 4mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 80mm; top: 154mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid1.png" class="w-full h-full object-contain" style="transform: rotate(8deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 6: ships 18(4), 18(5), 14(3) — L-R-L -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin7.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/splitters/splitter8.png" class="w-[66%] shrink-0 object-contain" style="transform: scaleX(-1);" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: -82mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay4.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">18</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay5.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">18</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay6.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">14</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 79mm; top: 24mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(65deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 65mm; top: -5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(1.35);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">7</span></div></div></div>
|
||||
<div class="absolute" style="left: 148mm; top: 18mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(73deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 99mm; top: 135mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(-42deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 47mm; top: 59mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(20deg) scale(0.45);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">1</span></div></div></div>
|
||||
<div class="absolute" style="left: 84mm; top: 48mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(40deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 114mm; top: 21mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(53deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 7mm; top: 80mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(0.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 65mm; top: 82mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 84mm; top: 82mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 146mm; top: 157mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid16.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 60mm; top: 108mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 81mm; top: 113mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 80mm; top: 160mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid5.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 7: ships 10(2), 16(3), 22(6) — R-L-R -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin4.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<img src="../../assets/hero-images/splitters/splitter9.png" class="w-[66%] shrink-0 object-contain" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: 120mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay7.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 29%; top: 51%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">25</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay8.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 71%; top: 45%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">21</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay9.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 23%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">32</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 37mm; top: 4mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-10deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 78mm; top: -3mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(17deg) scale(2.30);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 112mm; top: -1mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(50deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 2mm; top: 13mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(1.50);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 65mm; top: 34mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(2.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">11</span></div></div></div>
|
||||
<div class="absolute" style="left: 99mm; top: 45mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-5deg) scale(0.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 72mm; top: 107mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-55deg) scale(1.35);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">7</span></div></div></div>
|
||||
<div class="absolute" style="left: 78mm; top: 71mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(2.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 132mm; top: 81mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: -10mm; top: 140mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 38mm; top: 130mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid7.png" class="w-full h-full object-contain" style="transform: rotate(5deg) scale(3.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">13</span></div></div></div>
|
||||
<div class="absolute" style="left: 88mm; top: 155mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid11.png" class="w-full h-full object-contain" style="transform: rotate(-118deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 8: ships 26(0), 18(0), 30(0) — UNSOLVABLE — L-R-L -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin1.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/splitters/splitter5.png" class="w-[66%] shrink-0 object-contain" style="transform: scaleX(-1);" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: -82mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay1.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 35%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">26</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay2.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 29%; top: 39%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">28</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay3.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 74%; top: 51%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">30</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 70mm; top: 13mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(-13deg) scale(1.50);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 172mm; top: 7mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(-38deg) scale(1.80);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 36mm; top: -5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(-43deg) scale(1.35);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">7</span></div></div></div>
|
||||
<div class="absolute" style="left: 108mm; top: 10mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 41mm; top: 50mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(1.50);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: 78mm; top: 63mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(0.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 97mm; top: 41mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(-30deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: -5mm; top: 83mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(-25deg) scale(1.80);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 56mm; top: 88mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(-35deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 102mm; top: 100mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(3deg) scale(1.35);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">7</span></div></div></div>
|
||||
<div class="absolute" style="left: 147mm; top: 142mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid4.png" class="w-full h-full object-contain" style="transform: rotate(20deg) scale(1.80);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">10</span></div></div></div>
|
||||
<div class="absolute" style="left: 59mm; top: 132mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(5deg) scale(1.35);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">7</span></div></div></div>
|
||||
<div class="absolute" style="left: 95mm; top: 146mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid14.png" class="w-full h-full object-contain" style="transform: rotate(-7deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 9: ships 8(2), 18(3), 28(8) — R-L-R -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white">
|
||||
<div class="absolute bottom-0 left-0 right-0 z-0">
|
||||
<div class="absolute top-0 left-0 right-0 z-10" style="height: 10%; background: linear-gradient(to bottom, white, transparent);"></div>
|
||||
<img src="../../assets/footers/cabin8.jpeg" class="w-full" alt="">
|
||||
</div>
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[1mm] pb-[65mm] flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<img src="../../assets/hero-images/splitters/splitter3.png" class="w-[66%] shrink-0 object-contain" alt="">
|
||||
<div class="w-[34%] shrink-0 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Собери Астероиды</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-0.5">Загрузи трюмы кораблей!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div class="absolute" style="left: 120mm; top: 2%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay4.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 27%; top: 33%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">26</span></div></div></div>
|
||||
<div class="absolute" style="left: -82mm; top: 30%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay5.png" class="w-[500px] object-contain" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 65%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">18</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 58%;"><div class="relative"><img src="../../assets/icons/pack4-cargobay/cargo-bay6.png" class="w-[500px] min-w-[500px] object-contain" style="transform: scaleX(-1);" alt=""><div class="absolute w-12 h-12 rounded-full bg-indigo-600 flex items-center justify-center border-2 border-indigo-300 shadow-lg" style="left: 35%; top: 50%; transform: translate(-50%, -50%);"><span class="text-white font-extrabold text-xl">34</span></div></div></div>
|
||||
|
||||
<div class="absolute" style="left: 45mm; top: 1mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(-20deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 95mm; top: 6mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(15deg) scale(0.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 125mm; top: -5mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(-8deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: -10mm; top: 16mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(22deg) scale(1.35);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">7</span></div></div></div>
|
||||
<div class="absolute" style="left: 72mm; top: 35mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(-15deg) scale(1.35);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">7</span></div></div></div>
|
||||
<div class="absolute" style="left: 27mm; top: 38mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(10deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 120mm; top: 67mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(25deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
<div class="absolute" style="left: 57mm; top: 91mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(-12deg) scale(1.65);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">9</span></div></div></div>
|
||||
<div class="absolute" style="left: 91mm; top: 63mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(18deg) scale(0.60);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">2</span></div></div></div>
|
||||
<div class="absolute" style="left: 175mm; top: 81mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(-5deg) scale(1.50);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">8</span></div></div></div>
|
||||
<div class="absolute" style="left: -5mm; top: 123mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid6.png" class="w-full h-full object-contain" style="transform: rotate(12deg) scale(0.90);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">4</span></div></div></div>
|
||||
<div class="absolute" style="left: 67mm; top: 139mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(-22deg) scale(1.20);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">6</span></div></div></div>
|
||||
<div class="absolute" style="left: 108mm; top: 95mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(8deg) scale(0.75);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">3</span></div></div></div>
|
||||
<div class="absolute" style="left: 15mm; top: 155mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(20deg) scale(2.10);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">12</span></div></div></div>
|
||||
<div class="absolute" style="left: 99mm; top: 160mm;"><div class="relative w-[88px] h-[88px]"><img src="../../assets/icons/pack3-asteroids/asteroid10.png" class="w-full h-full object-contain" style="transform: rotate(-18deg) scale(1.05);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow: 0 0 6px rgba(0,0,0,0.9), 0 2px 4px rgba(0,0,0,0.7);">5</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,489 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Asteroid Position Editor</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { background: #1e1e2e; color: #cdd6f4; font-family: 'Segoe UI', system-ui, sans-serif; }
|
||||
|
||||
#toolbar {
|
||||
position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
|
||||
background: #181825; border-bottom: 1px solid #313244;
|
||||
display: flex; align-items: center; gap: 12px; padding: 8px 16px; height: 48px;
|
||||
}
|
||||
#toolbar button {
|
||||
background: #313244; color: #cdd6f4; border: 1px solid #45475a;
|
||||
padding: 6px 14px; border-radius: 6px; cursor: pointer; font-size: 13px;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
#toolbar button:hover { background: #45475a; }
|
||||
#toolbar button.primary { background: #6366f1; border-color: #818cf8; color: white; }
|
||||
#toolbar button.primary:hover { background: #818cf8; }
|
||||
#toolbar .page-nav { display: flex; align-items: center; gap: 6px; }
|
||||
#toolbar .page-nav span { font-size: 14px; min-width: 90px; text-align: center; }
|
||||
#toolbar .spacer { flex: 1; }
|
||||
#toolbar .title { font-weight: 600; font-size: 14px; color: #a6adc8; }
|
||||
|
||||
#statusbar {
|
||||
position: fixed; bottom: 0; left: 0; right: 0; z-index: 1000;
|
||||
background: #181825; border-top: 1px solid #313244;
|
||||
padding: 6px 16px; font-size: 13px; height: 32px;
|
||||
display: flex; align-items: center; gap: 20px;
|
||||
}
|
||||
#statusbar .pos { color: #89b4fa; }
|
||||
#statusbar .info { color: #a6adc8; }
|
||||
|
||||
#worksheet-container {
|
||||
padding: 48px 0 32px;
|
||||
display: flex; flex-direction: column; align-items: center; gap: 20px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.editor-draggable { cursor: grab; user-select: none; }
|
||||
.editor-draggable:hover { outline: 2px solid rgba(99, 102, 241, 0.5); outline-offset: 2px; border-radius: 50%; }
|
||||
.editor-selected { outline: 3px solid #6366f1 !important; outline-offset: 2px; border-radius: 50%; }
|
||||
.editor-changed::after {
|
||||
content: ''; position: absolute; top: 2px; right: 2px;
|
||||
width: 8px; height: 8px; background: #f59e0b; border-radius: 50%;
|
||||
border: 1px solid #1e1e2e;
|
||||
}
|
||||
body.dragging { cursor: grabbing !important; }
|
||||
body.dragging * { cursor: grabbing !important; }
|
||||
|
||||
.ship-draggable { z-index: 50; }
|
||||
.ship-draggable:hover { outline-color: rgba(251, 146, 60, 0.6); }
|
||||
.ship-selected { outline-color: #fb923c !important; }
|
||||
|
||||
#coord-tooltip {
|
||||
position: fixed; z-index: 2000; pointer-events: none;
|
||||
background: #181825; color: #89b4fa; border: 1px solid #6366f1;
|
||||
padding: 3px 8px; border-radius: 4px; font-size: 12px; font-family: monospace;
|
||||
display: none;
|
||||
}
|
||||
#toast {
|
||||
position: fixed; top: 60px; right: 16px; z-index: 2000;
|
||||
background: #6366f1; color: white; padding: 8px 16px; border-radius: 6px;
|
||||
font-size: 13px; opacity: 0; transition: opacity 0.3s; pointer-events: none;
|
||||
}
|
||||
#toast.show { opacity: 1; }
|
||||
.page-label {
|
||||
position: absolute; top: 4px; right: 4px; z-index: 100;
|
||||
background: rgba(0,0,0,0.6); color: white; padding: 2px 8px;
|
||||
border-radius: 4px; font-size: 12px; pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="toolbar">
|
||||
<span class="title">Asteroid Editor</span>
|
||||
<div class="page-nav">
|
||||
<button id="btn-prev" title="Previous page">←</button>
|
||||
<span id="page-indicator">Page 1 / ?</span>
|
||||
<button id="btn-next" title="Next page">→</button>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
<button id="btn-reset">Reset Page</button>
|
||||
<button id="btn-copy-changes">Copy Changes</button>
|
||||
<button id="btn-copy" class="primary">Copy All JSON</button>
|
||||
<button id="btn-save" class="primary" style="background:#22c55e;border-color:#4ade80;">Save</button>
|
||||
</div>
|
||||
|
||||
<div id="worksheet-container"></div>
|
||||
|
||||
<div id="statusbar">
|
||||
<span id="status-info" class="info">Click an asteroid or ship circle to select it</span>
|
||||
<span id="status-pos" class="pos"></span>
|
||||
</div>
|
||||
|
||||
<div id="coord-tooltip"></div>
|
||||
<div id="toast"></div>
|
||||
|
||||
<script src="/src/editor/editor-core.js"></script>
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
// === Asteroid-specific state ===
|
||||
const baseScales = {};
|
||||
let asteroids = [];
|
||||
let ships = [];
|
||||
let originalPositions = new Map();
|
||||
let selectedElement = null;
|
||||
let dragging = null;
|
||||
let dragStart = null;
|
||||
|
||||
// Scale formula
|
||||
function getBaseKey(p, t) { return 'p' + p + '-' + t; }
|
||||
function getBaseScale(p, t) { return baseScales[getBaseKey(p, t)] || 0.30; }
|
||||
function setBaseScale(p, t, v) { baseScales[getBaseKey(p, t)] = Math.round(v * 100) / 100; }
|
||||
function valueToScale(val, p, t) { return ((p && t) ? getBaseScale(p, t) : 0.30) + 0.15 * val; }
|
||||
|
||||
// === Init via EditorCore ===
|
||||
const core = EditorCore.init({
|
||||
taskType: 'collecting-asteroids',
|
||||
serialize: buildConfig,
|
||||
onReset: resetCurrentPage,
|
||||
onReady: function(pages, mmToPx) {
|
||||
setupAsteroids(pages);
|
||||
setupShips(pages);
|
||||
setupGlobalEvents(mmToPx);
|
||||
window.getConfig = () => buildConfig(false);
|
||||
window.getChanges = () => buildConfig(true);
|
||||
}
|
||||
});
|
||||
|
||||
if (!core) return;
|
||||
|
||||
// === Setup asteroids ===
|
||||
function setupAsteroids(pages) {
|
||||
document.querySelectorAll('.absolute:has(img[src*="pack3-asteroids"])').forEach((el, globalIndex) => {
|
||||
const page = el.closest('[data-page]');
|
||||
const pageNum = page ? parseInt(page.dataset.page) : 0;
|
||||
const left = parseFloat(el.style.left) || 0;
|
||||
const top = parseFloat(el.style.top) || 0;
|
||||
const img = el.querySelector('img[src*="pack3-asteroids"]');
|
||||
const span = el.querySelector('span');
|
||||
const astMatch = img ? img.src.match(/asteroid\d+/) : null;
|
||||
|
||||
let rotate = 0, scale = 1;
|
||||
if (img && img.style.transform) {
|
||||
const rotMatch = img.style.transform.match(/rotate\(([-\d.]+)deg\)/);
|
||||
const scMatch = img.style.transform.match(/scale\(([\d.]+)\)/);
|
||||
if (rotMatch) rotate = parseFloat(rotMatch[1]);
|
||||
if (scMatch) scale = parseFloat(scMatch[1]);
|
||||
}
|
||||
|
||||
const value = span ? parseInt(span.textContent.trim()) || 0 : 0;
|
||||
const id = `p${pageNum}-a${globalIndex}`;
|
||||
el.dataset.editorId = id;
|
||||
el.dataset.editorType = 'asteroid';
|
||||
el.dataset.pageNum = pageNum;
|
||||
|
||||
originalPositions.set(id, { left, top, rotate, scale, value });
|
||||
el.classList.add('editor-draggable');
|
||||
el.querySelectorAll('img').forEach(i => { i.style.pointerEvents = 'none'; i.draggable = false; });
|
||||
|
||||
asteroids.push({ el, id, pageNum, globalIndex, span, value, asteroid: astMatch ? astMatch[0] : 'unknown' });
|
||||
|
||||
el.addEventListener('mousedown', (e) => {
|
||||
e.preventDefault(); e.stopPropagation();
|
||||
selectElement(el, id, 'asteroid');
|
||||
startDragAsteroid(el, e);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// === Setup ships ===
|
||||
function setupShips(pages) {
|
||||
document.querySelectorAll('.rounded-full.bg-indigo-600').forEach((circleEl, globalIndex) => {
|
||||
const page = circleEl.closest('[data-page]');
|
||||
const pageNum = page ? parseInt(page.dataset.page) : 0;
|
||||
const span = circleEl.querySelector('span');
|
||||
const value = span ? parseInt(span.textContent.trim()) || 0 : 0;
|
||||
const origLeft = circleEl.style.left || '50%';
|
||||
const origTop = circleEl.style.top || '50%';
|
||||
|
||||
const id = `p${pageNum}-s${globalIndex}`;
|
||||
circleEl.dataset.editorId = id;
|
||||
circleEl.dataset.editorType = 'ship';
|
||||
circleEl.dataset.pageNum = pageNum;
|
||||
|
||||
originalPositions.set(id, { left: origLeft, top: origTop, value });
|
||||
circleEl.classList.add('editor-draggable', 'ship-draggable');
|
||||
circleEl.style.cursor = 'grab';
|
||||
|
||||
ships.push({ el: circleEl, id, pageNum, globalIndex, span, value });
|
||||
|
||||
circleEl.addEventListener('mousedown', (e) => {
|
||||
e.preventDefault(); e.stopPropagation();
|
||||
selectElement(circleEl, id, 'ship');
|
||||
startDragShip(circleEl, e);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// === Global events ===
|
||||
function setupGlobalEvents(mmToPx) {
|
||||
document.addEventListener('mousemove', onMouseMove);
|
||||
document.addEventListener('mouseup', onMouseUp);
|
||||
document.addEventListener('keydown', onKeyDown);
|
||||
|
||||
document.getElementById('worksheet-container').addEventListener('mousedown', (e) => {
|
||||
if (!e.target.closest('.editor-draggable')) deselectAll();
|
||||
});
|
||||
}
|
||||
|
||||
// === Selection ===
|
||||
function selectElement(el, id, type) {
|
||||
deselectAll();
|
||||
el.classList.add(type === 'ship' ? 'ship-selected' : 'editor-selected');
|
||||
selectedElement = { el, id, type };
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
function deselectAll() {
|
||||
document.querySelectorAll('.editor-selected, .ship-selected').forEach(el => {
|
||||
el.classList.remove('editor-selected', 'ship-selected');
|
||||
});
|
||||
selectedElement = null;
|
||||
document.getElementById('status-info').textContent = 'Click an asteroid or ship circle to select it';
|
||||
document.getElementById('status-pos').textContent = '';
|
||||
}
|
||||
|
||||
// === Asteroid helpers ===
|
||||
function getAsteroidTransform(el) {
|
||||
const img = el.querySelector('img[src*="pack3-asteroids"]');
|
||||
let rotate = 0, scale = 1;
|
||||
if (img && img.style.transform) {
|
||||
const rotMatch = img.style.transform.match(/rotate\(([-\d.]+)deg\)/);
|
||||
const scMatch = img.style.transform.match(/scale\(([\d.]+)\)/);
|
||||
if (rotMatch) rotate = parseFloat(rotMatch[1]);
|
||||
if (scMatch) scale = parseFloat(scMatch[1]);
|
||||
}
|
||||
return { rotate, scale, img };
|
||||
}
|
||||
|
||||
function setAsteroidTransform(el, rotate, scale) {
|
||||
const img = el.querySelector('img[src*="pack3-asteroids"]');
|
||||
if (img) img.style.transform = `rotate(${rotate}deg) scale(${scale.toFixed(2)})`;
|
||||
}
|
||||
|
||||
// === Status ===
|
||||
function updateStatus() {
|
||||
if (!selectedElement) return;
|
||||
const { el, id, type } = selectedElement;
|
||||
|
||||
if (type === 'asteroid') {
|
||||
const left = Math.round(parseFloat(el.style.left));
|
||||
const top = Math.round(parseFloat(el.style.top));
|
||||
const { rotate, scale } = getAsteroidTransform(el);
|
||||
const ast = asteroids.find(a => a.id === id);
|
||||
const base = ast ? getBaseScale(parseInt(el.dataset.pageNum), ast.asteroid) : 0.30;
|
||||
document.getElementById('status-info').textContent =
|
||||
`Page ${el.dataset.pageNum} | val=${ast ? ast.value : '?'} | ${ast ? ast.asteroid : ''} | base=${base.toFixed(2)} | [/] rot, +/- val, </.> base`;
|
||||
document.getElementById('status-pos').textContent =
|
||||
`left: ${left}mm, top: ${top}mm | rot: ${Math.round(rotate)}° | scale: ${scale.toFixed(2)}`;
|
||||
} else {
|
||||
const ship = ships.find(s => s.id === id);
|
||||
document.getElementById('status-info').textContent =
|
||||
`Page ${el.dataset.pageNum} | Ship capacity=${ship ? ship.value : '?'} | +/- change value`;
|
||||
document.getElementById('status-pos').textContent =
|
||||
`left: ${el.style.left}, top: ${el.style.top}`;
|
||||
}
|
||||
}
|
||||
|
||||
// === Dragging ===
|
||||
function startDragAsteroid(el, e) {
|
||||
dragging = { el, type: 'asteroid' };
|
||||
dragStart = { mouseX: e.clientX, mouseY: e.clientY, left: parseFloat(el.style.left) || 0, top: parseFloat(el.style.top) || 0 };
|
||||
document.body.classList.add('dragging');
|
||||
}
|
||||
|
||||
function startDragShip(el, e) {
|
||||
const parent = el.offsetParent || el.parentElement;
|
||||
dragging = { el, type: 'ship', parentRect: parent.getBoundingClientRect() };
|
||||
dragStart = { mouseX: e.clientX, mouseY: e.clientY, leftPct: parseFloat(el.style.left) || 50, topPct: parseFloat(el.style.top) || 50 };
|
||||
document.body.classList.add('dragging');
|
||||
}
|
||||
|
||||
function onMouseMove(e) {
|
||||
if (!dragging) return;
|
||||
e.preventDefault();
|
||||
|
||||
if (dragging.type === 'asteroid') {
|
||||
const dx = (e.clientX - dragStart.mouseX) / core.mmToPx;
|
||||
const dy = (e.clientY - dragStart.mouseY) / core.mmToPx;
|
||||
let newLeft = Math.max(-10, Math.min(175, Math.round(dragStart.left + dx)));
|
||||
let newTop = Math.max(-5, Math.min(160, Math.round(dragStart.top + dy)));
|
||||
dragging.el.style.left = newLeft + 'mm';
|
||||
dragging.el.style.top = newTop + 'mm';
|
||||
core.showTooltip(e, `${newLeft}mm, ${newTop}mm`);
|
||||
} else if (dragging.type === 'ship') {
|
||||
const pW = dragging.parentRect.width;
|
||||
const pH = dragging.parentRect.height;
|
||||
if (pW === 0 || pH === 0) return;
|
||||
let newLeftPct = Math.round(dragStart.leftPct + ((e.clientX - dragStart.mouseX) / pW) * 100);
|
||||
let newTopPct = Math.round(dragStart.topPct + ((e.clientY - dragStart.mouseY) / pH) * 100);
|
||||
dragging.el.style.left = newLeftPct + '%';
|
||||
dragging.el.style.top = newTopPct + '%';
|
||||
core.showTooltip(e, `${newLeftPct}%, ${newTopPct}%`);
|
||||
}
|
||||
|
||||
updateStatus();
|
||||
markChanged(dragging.el);
|
||||
}
|
||||
|
||||
function onMouseUp() {
|
||||
if (!dragging) return;
|
||||
document.body.classList.remove('dragging');
|
||||
core.hideTooltip();
|
||||
dragging = null; dragStart = null;
|
||||
}
|
||||
|
||||
// === Keyboard ===
|
||||
function onKeyDown(e) {
|
||||
if (!selectedElement) return;
|
||||
const { el, id, type } = selectedElement;
|
||||
if (type === 'asteroid') onKeyDownAsteroid(e, el, id);
|
||||
else onKeyDownShip(e, el, id);
|
||||
}
|
||||
|
||||
function onKeyDownAsteroid(e, el, id) {
|
||||
const step = e.shiftKey ? 5 : 1;
|
||||
let left = parseFloat(el.style.left) || 0;
|
||||
let top = parseFloat(el.style.top) || 0;
|
||||
const { rotate, scale } = getAsteroidTransform(el);
|
||||
const rotStep = e.shiftKey ? 1 : 5;
|
||||
const ast = asteroids.find(a => a.id === id);
|
||||
const pageNum = parseInt(el.dataset.pageNum);
|
||||
|
||||
switch (e.key) {
|
||||
case 'ArrowLeft': left -= step; break;
|
||||
case 'ArrowRight': left += step; break;
|
||||
case 'ArrowUp': top -= step; break;
|
||||
case 'ArrowDown': top += step; break;
|
||||
case '[': setAsteroidTransform(el, rotate - rotStep, scale); break;
|
||||
case ']': setAsteroidTransform(el, rotate + rotStep, scale); break;
|
||||
case '-': case '_':
|
||||
if (ast && ast.value > 1) { ast.value--; ast.span.textContent = ast.value; setAsteroidTransform(el, rotate, valueToScale(ast.value, pageNum, ast.asteroid)); }
|
||||
break;
|
||||
case '=': case '+':
|
||||
if (ast && ast.value < 20) { ast.value++; ast.span.textContent = ast.value; setAsteroidTransform(el, rotate, valueToScale(ast.value, pageNum, ast.asteroid)); }
|
||||
break;
|
||||
case ',': case '<':
|
||||
if (ast) { const bs = e.shiftKey ? 0.01 : 0.05; setBaseScale(pageNum, ast.asteroid, Math.max(0.05, getBaseScale(pageNum, ast.asteroid) - bs)); applyBaseToType(pageNum, ast.asteroid); core.showToast(`Base ${ast.asteroid}: ${getBaseScale(pageNum, ast.asteroid).toFixed(2)}`); }
|
||||
break;
|
||||
case '.': case '>':
|
||||
if (ast) { const bs = e.shiftKey ? 0.01 : 0.05; setBaseScale(pageNum, ast.asteroid, getBaseScale(pageNum, ast.asteroid) + bs); applyBaseToType(pageNum, ast.asteroid); core.showToast(`Base ${ast.asteroid}: ${getBaseScale(pageNum, ast.asteroid).toFixed(2)}`); }
|
||||
break;
|
||||
case 'Escape': deselectAll(); return;
|
||||
default: return;
|
||||
}
|
||||
e.preventDefault();
|
||||
el.style.left = Math.max(-10, Math.min(175, Math.round(left))) + 'mm';
|
||||
el.style.top = Math.max(-5, Math.min(160, Math.round(top))) + 'mm';
|
||||
updateStatus(); markChanged(el);
|
||||
}
|
||||
|
||||
function onKeyDownShip(e, el, id) {
|
||||
const ship = ships.find(s => s.id === id);
|
||||
if (!ship) return;
|
||||
const step = e.shiftKey ? 5 : 1;
|
||||
|
||||
switch (e.key) {
|
||||
case '-': case '_': ship.value = Math.max(1, ship.value - step); ship.span.textContent = ship.value; break;
|
||||
case '=': case '+': ship.value += step; ship.span.textContent = ship.value; break;
|
||||
case 'ArrowLeft': el.style.left = ((parseFloat(el.style.left) || 50) - step) + '%'; break;
|
||||
case 'ArrowRight': el.style.left = ((parseFloat(el.style.left) || 50) + step) + '%'; break;
|
||||
case 'ArrowUp': el.style.top = ((parseFloat(el.style.top) || 50) - step) + '%'; break;
|
||||
case 'ArrowDown': el.style.top = ((parseFloat(el.style.top) || 50) + step) + '%'; break;
|
||||
case 'Escape': deselectAll(); return;
|
||||
default: return;
|
||||
}
|
||||
e.preventDefault(); updateStatus(); markChanged(el);
|
||||
}
|
||||
|
||||
// === Change tracking ===
|
||||
function markChanged(el) {
|
||||
const id = el.dataset.editorId;
|
||||
const type = el.dataset.editorType;
|
||||
const orig = originalPositions.get(id);
|
||||
if (!orig) return;
|
||||
|
||||
let changed = false;
|
||||
if (type === 'asteroid') {
|
||||
const { rotate, scale } = getAsteroidTransform(el);
|
||||
const ast = asteroids.find(a => a.id === id);
|
||||
changed = Math.round(orig.left) !== Math.round(parseFloat(el.style.left)) ||
|
||||
Math.round(orig.top) !== Math.round(parseFloat(el.style.top)) ||
|
||||
Math.round(orig.rotate) !== Math.round(rotate) ||
|
||||
Math.abs(orig.scale - scale) > 0.005 ||
|
||||
(ast && orig.value !== ast.value);
|
||||
} else {
|
||||
const ship = ships.find(s => s.id === id);
|
||||
changed = el.style.left !== orig.left || el.style.top !== orig.top || (ship && orig.value !== ship.value);
|
||||
}
|
||||
el.classList.toggle('editor-changed', changed);
|
||||
}
|
||||
|
||||
function applyBaseToType(pageNum, asteroidType) {
|
||||
asteroids.filter(a => a.pageNum === pageNum && a.asteroid === asteroidType).forEach(ast => {
|
||||
const { rotate } = getAsteroidTransform(ast.el);
|
||||
setAsteroidTransform(ast.el, rotate, valueToScale(ast.value, pageNum, asteroidType));
|
||||
markChanged(ast.el);
|
||||
});
|
||||
}
|
||||
|
||||
// === Serialization ===
|
||||
function buildConfig(changesOnly) {
|
||||
const result = { file: core.docId, pages: [] };
|
||||
|
||||
core.pages.forEach((pageEl, pageIndex) => {
|
||||
const pageNum = pageIndex + 1;
|
||||
const pageData = { page: pageNum };
|
||||
|
||||
const pageAsteroids = asteroids.filter(a => a.pageNum === pageNum);
|
||||
const asteroidItems = [];
|
||||
pageAsteroids.forEach((ast, localIndex) => {
|
||||
const curLeft = Math.round(parseFloat(ast.el.style.left));
|
||||
const curTop = Math.round(parseFloat(ast.el.style.top));
|
||||
const { rotate, scale } = getAsteroidTransform(ast.el);
|
||||
const orig = originalPositions.get(ast.id);
|
||||
if (changesOnly && orig &&
|
||||
Math.round(orig.left) === curLeft && Math.round(orig.top) === curTop &&
|
||||
Math.round(orig.rotate) === Math.round(rotate) && Math.abs(orig.scale - scale) < 0.005 &&
|
||||
orig.value === ast.value) return;
|
||||
asteroidItems.push({ index: localIndex, left: curLeft + 'mm', top: curTop + 'mm', rotate: Math.round(rotate) + 'deg', scale: parseFloat(scale.toFixed(2)), value: ast.value, asteroid: ast.asteroid });
|
||||
});
|
||||
|
||||
const pageShips = ships.filter(s => s.pageNum === pageNum);
|
||||
const shipItems = [];
|
||||
pageShips.forEach((ship, localIndex) => {
|
||||
const orig = originalPositions.get(ship.id);
|
||||
if (changesOnly && orig && ship.el.style.left === orig.left && ship.el.style.top === orig.top && orig.value === ship.value) return;
|
||||
shipItems.push({ index: localIndex, left: ship.el.style.left, top: ship.el.style.top, value: ship.value });
|
||||
});
|
||||
|
||||
const pageBaseScales = {};
|
||||
for (const [key, val] of Object.entries(baseScales)) {
|
||||
if (key.startsWith('p' + pageNum + '-') && val !== 0.30) {
|
||||
pageBaseScales[key.replace('p' + pageNum + '-', '')] = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (asteroidItems.length > 0 || shipItems.length > 0 || Object.keys(pageBaseScales).length > 0) {
|
||||
if (asteroidItems.length > 0) pageData.asteroids = asteroidItems;
|
||||
if (shipItems.length > 0) pageData.ships = shipItems;
|
||||
if (Object.keys(pageBaseScales).length > 0) pageData.baseScales = pageBaseScales;
|
||||
result.pages.push(pageData);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
// === Reset ===
|
||||
function resetCurrentPage(pageNum) {
|
||||
asteroids.filter(a => a.pageNum === pageNum).forEach(ast => {
|
||||
const orig = originalPositions.get(ast.id);
|
||||
if (!orig) return;
|
||||
ast.el.style.left = orig.left + 'mm'; ast.el.style.top = orig.top + 'mm';
|
||||
setAsteroidTransform(ast.el, orig.rotate, orig.scale);
|
||||
ast.value = orig.value; ast.span.textContent = orig.value;
|
||||
ast.el.classList.remove('editor-changed');
|
||||
});
|
||||
ships.filter(s => s.pageNum === pageNum).forEach(ship => {
|
||||
const orig = originalPositions.get(ship.id);
|
||||
if (!orig) return;
|
||||
ship.el.style.left = orig.left; ship.el.style.top = orig.top;
|
||||
ship.value = orig.value; ship.span.textContent = orig.value;
|
||||
ship.el.classList.remove('editor-changed');
|
||||
});
|
||||
core.showToast(`Page ${pageNum} reset`);
|
||||
}
|
||||
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,171 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Generate output HTML from template + data for collecting-asteroids documents.
|
||||
*
|
||||
* Usage: node generate.mjs <docId>
|
||||
* Example: node generate.mjs collecting-asteroids-3
|
||||
*
|
||||
* Reads: docs/<docId>.template.html
|
||||
* Reads: docs/<docId>.data.json (optional)
|
||||
* Writes: docs/<docId>.output.html
|
||||
*
|
||||
* data.json format:
|
||||
* {
|
||||
* pages: [{
|
||||
* page: 1,
|
||||
* asteroids: [{ index, left, top, rotate, scale, value, asteroid }],
|
||||
* ships: [{ index, left, top, value }],
|
||||
* baseScales: { "asteroid5": 0.35 }
|
||||
* }]
|
||||
* }
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
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 <docId>');
|
||||
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'));
|
||||
html = applyData(html, data);
|
||||
console.log(`Applied data from ${data.pages?.length || 0} pages`);
|
||||
}
|
||||
|
||||
writeFileSync(outputPath, html);
|
||||
console.log(`Generated: ${outputPath}`);
|
||||
|
||||
function applyData(html, data) {
|
||||
if (!data.pages) return html;
|
||||
|
||||
// Split HTML into pages by PAGE comment markers or by w-[210mm] divs
|
||||
const pageMarker = /<!-- PAGE (\d+)/g;
|
||||
const hasPageComments = pageMarker.test(html);
|
||||
|
||||
if (hasPageComments) {
|
||||
// Split by page comments
|
||||
return applyByPageComments(html, data.pages);
|
||||
} else {
|
||||
// Split by page divs
|
||||
return applyByPageDivs(html, data.pages);
|
||||
}
|
||||
}
|
||||
|
||||
function applyByPageDivs(html, pages) {
|
||||
// Find page boundaries: <div class="w-[210mm] h-[297mm]"
|
||||
const pageRegex = /<div class="w-\[210mm\] h-\[297mm\]"/g;
|
||||
const starts = [];
|
||||
let match;
|
||||
while ((match = pageRegex.exec(html)) !== null) {
|
||||
starts.push(match.index);
|
||||
}
|
||||
|
||||
if (starts.length === 0) return html;
|
||||
|
||||
// Process pages in reverse order to preserve indices
|
||||
for (let i = pages.length - 1; i >= 0; i--) {
|
||||
const pageData = pages[i];
|
||||
const pageNum = pageData.page || (i + 1);
|
||||
const pageIdx = pageNum - 1;
|
||||
|
||||
if (pageIdx >= starts.length) continue;
|
||||
|
||||
const pageStart = starts[pageIdx];
|
||||
const pageEnd = pageIdx + 1 < starts.length ? starts[pageIdx + 1] : html.length;
|
||||
let pageHtml = html.slice(pageStart, pageEnd);
|
||||
|
||||
// Apply asteroid positions
|
||||
if (pageData.asteroids) {
|
||||
pageHtml = applyAsteroids(pageHtml, pageData.asteroids);
|
||||
}
|
||||
|
||||
// Apply ship positions
|
||||
if (pageData.ships) {
|
||||
pageHtml = applyShips(pageHtml, pageData.ships);
|
||||
}
|
||||
|
||||
html = html.slice(0, pageStart) + pageHtml + html.slice(pageEnd);
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function applyByPageComments(html, pages) {
|
||||
// Same logic but split by <!-- PAGE N -->
|
||||
const parts = html.split(/(<!-- PAGE \d+)/);
|
||||
const pageChunks = [];
|
||||
let prelude = parts[0];
|
||||
|
||||
for (let i = 1; i < parts.length; i += 2) {
|
||||
pageChunks.push(parts[i] + (parts[i + 1] || ''));
|
||||
}
|
||||
|
||||
for (const pageData of pages) {
|
||||
const pageIdx = (pageData.page || 1) - 1;
|
||||
if (pageIdx >= pageChunks.length) continue;
|
||||
|
||||
if (pageData.asteroids) {
|
||||
pageChunks[pageIdx] = applyAsteroids(pageChunks[pageIdx], pageData.asteroids);
|
||||
}
|
||||
if (pageData.ships) {
|
||||
pageChunks[pageIdx] = applyShips(pageChunks[pageIdx], pageData.ships);
|
||||
}
|
||||
}
|
||||
|
||||
return prelude + pageChunks.join('');
|
||||
}
|
||||
|
||||
function applyAsteroids(pageHtml, asteroids) {
|
||||
// Match asteroid containers: <div class="absolute" style="left: Xmm; top: Ymm;">
|
||||
// followed by pack3-asteroids image
|
||||
const asteroidRegex = /(<div class="absolute" style="left: )-?\d+mm; top: -?\d+mm(;"><div class="relative w-\[88px\] h-\[88px\]"><img src="[^"]*pack3-asteroids\/[^"]*" class="w-full h-full object-contain" style="transform: rotate\()-?\d+deg(\) scale\()[\d.]+(\);" alt=""><div class="absolute inset-0 flex items-center justify-center"><span class="text-white font-extrabold text-2xl" style="text-shadow[^"]*">)\d+(<\/span>)/g;
|
||||
|
||||
let idx = 0;
|
||||
return pageHtml.replace(asteroidRegex, (match, prefix, rotPrefix, scalePrefix, scaleSuffix, valueSuffix) => {
|
||||
const ast = asteroids[idx++];
|
||||
if (!ast) return match;
|
||||
|
||||
const left = ast.left.replace('mm', '');
|
||||
const top = ast.top.replace('mm', '');
|
||||
const rotate = ast.rotate.replace('deg', '');
|
||||
const scale = ast.scale.toFixed(2);
|
||||
const value = ast.value;
|
||||
|
||||
return `${prefix}${left}mm; top: ${top}mm${rotPrefix}${rotate}deg${scalePrefix}${scale}${scaleSuffix}${value}${valueSuffix}`;
|
||||
});
|
||||
}
|
||||
|
||||
function applyShips(pageHtml, ships) {
|
||||
// Match ship capacity circles
|
||||
const shipRegex = /(<div class="absolute w-12 h-12 rounded-full bg-indigo-600[^"]*" style="left: )[\d.]+%(; top: )[\d.]+(%[^>]*><span class="text-white font-extrabold text-xl">)\d+(<\/span>)/g;
|
||||
|
||||
let idx = 0;
|
||||
return pageHtml.replace(shipRegex, (match, prefix, topPrefix, valueSuffix, spanClose) => {
|
||||
const ship = ships[idx++];
|
||||
if (!ship) return match;
|
||||
|
||||
const left = ship.left.replace('%', '');
|
||||
const top = ship.top.replace('%', '');
|
||||
|
||||
return `${prefix}${left}%${topPrefix}${top}${valueSuffix}${ship.value}${spanClose}`;
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Transform collecting-asteroids-2.html into collecting-asteroids-3.html
|
||||
* Output goes to stdout for review before saving.
|
||||
*/
|
||||
|
||||
import { readFileSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
|
||||
const root = resolve(import.meta.dirname, '../..');
|
||||
const v2Html = readFileSync(resolve(root, 'output/html/collecting-asteroids-2.html'), 'utf-8');
|
||||
|
||||
// Page configs for v3
|
||||
const pages = [
|
||||
{
|
||||
comment: 'PAGE 1: ships 11(2), 9(2), 13(6) — R-L-R',
|
||||
hero: 'splitter4', footer: 'cabin3',
|
||||
cargoBays: [7, 8, 9],
|
||||
ships: [11, 9, 13],
|
||||
oldAsteroidTypes: ['asteroid7', 'asteroid14'],
|
||||
newAsteroidTypes: ['asteroid3', 'asteroid10'],
|
||||
asteroidValues: [3, 2, 1, 4, 5, 2, 3, 6, 5, 4, 1, 6],
|
||||
},
|
||||
{
|
||||
comment: 'PAGE 2: ships 12(3), 12(3), 18(4) — L-R-L',
|
||||
hero: 'splitter7', footer: 'cabin6',
|
||||
cargoBays: [1, 2, 3],
|
||||
ships: [12, 12, 18],
|
||||
oldAsteroidTypes: ['asteroid4', 'asteroid11'],
|
||||
newAsteroidTypes: ['asteroid6', 'asteroid13'],
|
||||
asteroidValues: [4, 5, 3, 6, 2, 7, 4, 3, 5, 2, 6, 4],
|
||||
},
|
||||
{
|
||||
comment: 'PAGE 3: ships 9(5), 11(3), 11(2) — R-L-R',
|
||||
hero: 'splitter1', footer: 'cabin9',
|
||||
cargoBays: [4, 5, 6],
|
||||
ships: [9, 11, 11],
|
||||
oldAsteroidTypes: ['asteroid10', 'asteroid3'],
|
||||
newAsteroidTypes: ['asteroid2', 'asteroid8'],
|
||||
asteroidValues: [2, 4, 1, 3, 5, 2, 1, 3, 4, 6, 5, 2],
|
||||
},
|
||||
{
|
||||
comment: 'PAGE 4: ships 15(4), 17(5), 11(2) — L-R-L',
|
||||
hero: 'splitter6', footer: 'cabin2',
|
||||
cargoBays: [7, 8, 9],
|
||||
ships: [15, 17, 11],
|
||||
oldAsteroidTypes: ['asteroid16', 'asteroid5'],
|
||||
newAsteroidTypes: ['asteroid12', 'asteroid15'],
|
||||
asteroidValues: [4, 3, 5, 2, 6, 1, 3, 4, 6, 2, 5, 4],
|
||||
},
|
||||
{
|
||||
comment: 'PAGE 5: ships 7(2), 9(4), 7(2) — R-L-R',
|
||||
hero: 'splitter2', footer: 'cabin5',
|
||||
cargoBays: [1, 2, 3],
|
||||
ships: [7, 9, 7],
|
||||
oldAsteroidTypes: ['asteroid2', 'asteroid13'],
|
||||
newAsteroidTypes: ['asteroid1', 'asteroid9'],
|
||||
asteroidValues: [3, 1, 4, 2, 5, 1, 6, 2, 3, 4, 5],
|
||||
},
|
||||
{
|
||||
comment: 'PAGE 6: ships 18(4), 18(5), 14(3) — L-R-L',
|
||||
hero: 'splitter8', footer: 'cabin7',
|
||||
cargoBays: [4, 5, 6],
|
||||
ships: [18, 18, 14],
|
||||
oldAsteroidTypes: ['asteroid8', 'asteroid12'],
|
||||
newAsteroidTypes: ['asteroid5', 'asteroid16'],
|
||||
asteroidValues: [3, 4, 5, 6, 2, 4, 7, 3, 2, 5, 6, 4, 3, 7],
|
||||
},
|
||||
{
|
||||
comment: 'PAGE 7: ships 10(2), 16(3), 22(6) — R-L-R',
|
||||
hero: 'splitter9', footer: 'cabin4',
|
||||
cargoBays: [7, 8, 9],
|
||||
ships: [10, 16, 22],
|
||||
oldAsteroidTypes: ['asteroid15', 'asteroid6'],
|
||||
newAsteroidTypes: ['asteroid11', 'asteroid7'],
|
||||
asteroidValues: [4, 3, 2, 6, 5, 3, 7, 4, 5, 2, 6, 4],
|
||||
},
|
||||
{
|
||||
comment: 'PAGE 8: ships 26(0), 18(0), 30(0) — UNSOLVABLE — L-R-L',
|
||||
hero: 'splitter5', footer: 'cabin1',
|
||||
cargoBays: [1, 2, 3],
|
||||
ships: [26, 18, 30],
|
||||
oldAsteroidTypes: ['asteroid9', 'asteroid1'],
|
||||
newAsteroidTypes: ['asteroid14', 'asteroid4'],
|
||||
asteroidValues: [6, 4, 5, 3, 7, 2, 4, 6, 5, 7, 3, 4, 6],
|
||||
},
|
||||
{
|
||||
comment: 'PAGE 9: ships 8(2), 18(3), 28(8) — R-L-R',
|
||||
hero: 'splitter3', footer: 'cabin8',
|
||||
cargoBays: [4, 5, 6],
|
||||
ships: [8, 18, 28],
|
||||
oldAsteroidTypes: ['asteroid11', 'asteroid4'],
|
||||
newAsteroidTypes: ['asteroid10', 'asteroid6'],
|
||||
asteroidValues: [4, 3, 2, 5, 6, 3, 4, 7, 2, 5, 4, 6, 3, 7, 5],
|
||||
},
|
||||
];
|
||||
|
||||
// Split HTML into pages
|
||||
// Pages are delimited by <!-- PAGE N comments
|
||||
const pageRegex = /<!-- PAGE \d+/g;
|
||||
const matches = [...v2Html.matchAll(pageRegex)];
|
||||
|
||||
// Extract page blocks
|
||||
const pageBlocks = [];
|
||||
for (let i = 0; i < matches.length; i++) {
|
||||
const start = matches[i].index;
|
||||
const end = i + 1 < matches.length ? matches[i + 1].index : v2Html.lastIndexOf('</body>');
|
||||
pageBlocks.push(v2Html.substring(start, end));
|
||||
}
|
||||
|
||||
// Extract header (before first page) and footer (after last page)
|
||||
const header = v2Html.substring(0, matches[0].index);
|
||||
const footer = v2Html.substring(v2Html.lastIndexOf('</body>'));
|
||||
|
||||
function transformPage(block, config, pageIdx) {
|
||||
let html = block;
|
||||
|
||||
// 1. Replace page comment
|
||||
html = html.replace(/<!-- PAGE \d+:.*?-->/, `<!-- ${config.comment} -->`);
|
||||
|
||||
// 2. Replace hero image
|
||||
html = html.replace(
|
||||
/splitters\/splitter\d+\.png/,
|
||||
`splitters/${config.hero}.png`
|
||||
);
|
||||
|
||||
// 3. Replace footer image
|
||||
html = html.replace(
|
||||
/footers\/cabin\d+\.jpeg/,
|
||||
`footers/${config.footer}.jpeg`
|
||||
);
|
||||
|
||||
// 4. Replace cargo bay images (3 per page, in order)
|
||||
let cbIdx = 0;
|
||||
html = html.replace(
|
||||
/pack4-cargobay\/cargo-bay\d+\.png/g,
|
||||
(match) => `pack4-cargobay/cargo-bay${config.cargoBays[cbIdx++]}.png`
|
||||
);
|
||||
|
||||
// 5. Replace ship capacity numbers (text-xl spans inside blue circles)
|
||||
let shipIdx = 0;
|
||||
html = html.replace(
|
||||
/(<span class="text-white font-extrabold text-xl">)(\d+)(<\/span>)/g,
|
||||
(match, pre, val, post) => `${pre}${config.ships[shipIdx++]}${post}`
|
||||
);
|
||||
|
||||
// 6. Replace asteroid type images
|
||||
for (let i = 0; i < config.oldAsteroidTypes.length; i++) {
|
||||
const oldType = config.oldAsteroidTypes[i];
|
||||
const newType = config.newAsteroidTypes[i];
|
||||
html = html.replaceAll(
|
||||
`pack3-asteroids/${oldType}.png`,
|
||||
`pack3-asteroids/${newType}.png`
|
||||
);
|
||||
}
|
||||
|
||||
// 7. Replace asteroid values (text-2xl spans, sequential)
|
||||
let avIdx = 0;
|
||||
html = html.replace(
|
||||
/(<span class="text-white font-extrabold text-2xl"[^>]*>)(\d+)(<\/span>)/g,
|
||||
(match, pre, val, post) => {
|
||||
if (avIdx < config.asteroidValues.length) {
|
||||
return `${pre}${config.asteroidValues[avIdx++]}${post}`;
|
||||
}
|
||||
return match;
|
||||
}
|
||||
);
|
||||
|
||||
// Sanity check
|
||||
if (shipIdx !== 3) {
|
||||
console.error(`WARNING: Page ${pageIdx + 1} — replaced ${shipIdx} ship values (expected 3)`);
|
||||
}
|
||||
if (avIdx !== config.asteroidValues.length) {
|
||||
console.error(`WARNING: Page ${pageIdx + 1} — replaced ${avIdx} asteroid values (expected ${config.asteroidValues.length})`);
|
||||
}
|
||||
if (cbIdx !== 3) {
|
||||
console.error(`WARNING: Page ${pageIdx + 1} — replaced ${cbIdx} cargo bay refs (expected 3)`);
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
// Transform all pages
|
||||
const newPages = pageBlocks.map((block, i) => transformPage(block, pages[i], i));
|
||||
|
||||
// Assemble
|
||||
const result = header + newPages.join('') + footer;
|
||||
|
||||
// Write to temp file
|
||||
import { writeFileSync } from 'fs';
|
||||
const tmpPath = resolve(root, 'output/html/.collecting-asteroids-3-tmp.html');
|
||||
writeFileSync(tmpPath, result);
|
||||
console.log(`Output written to: ${tmpPath}`);
|
||||
console.log(`Total lines: ${result.split('\n').length}`);
|
||||
|
||||
// Print summary of changes per page
|
||||
for (let i = 0; i < pages.length; i++) {
|
||||
const p = pages[i];
|
||||
console.log(`\nPage ${i + 1}: hero=${p.hero} footer=${p.footer} cargoBays=[${p.cargoBays}]`);
|
||||
console.log(` Ships: [${p.ships}] Asteroids: [${p.asteroidValues}]`);
|
||||
console.log(` Types: ${p.oldAsteroidTypes} → ${p.newAsteroidTypes}`);
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Asteroid partition solver.
|
||||
* Verifies that disjoint subsets of asteroid values can sum to each ship capacity.
|
||||
*
|
||||
* Usage:
|
||||
* node verify-asteroids.mjs --ships 10,10,14 --asteroids 3,2,1,4,5,2,3,6,5,4,1,6
|
||||
*
|
||||
* Output: prints whether a valid partition exists and one example solution.
|
||||
*/
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
function parseArg(flag) {
|
||||
const idx = args.indexOf(flag);
|
||||
if (idx === -1 || idx + 1 >= args.length) return null;
|
||||
return args[idx + 1].split(',').map(Number);
|
||||
}
|
||||
|
||||
const ships = parseArg('--ships');
|
||||
const asteroids = parseArg('--asteroids');
|
||||
|
||||
if (!ships || !asteroids) {
|
||||
console.log('Usage: node verify-asteroids.mjs --ships 10,10,14 --asteroids 3,2,1,4,5,2,3,6,5,4,1,6');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Ships: [${ships.join(', ')}] (sum=${ships.reduce((a, b) => a + b, 0)})`);
|
||||
console.log(`Asteroids: [${asteroids.join(', ')}] (count=${asteroids.length}, sum=${asteroids.reduce((a, b) => a + b, 0)})`);
|
||||
|
||||
/**
|
||||
* Find disjoint subsets of `available` (by index) that sum to each capacity in `capacities`.
|
||||
* Returns array of index arrays, or null if no solution.
|
||||
*/
|
||||
function findPartition(available, capacities, usedSet = new Set()) {
|
||||
if (capacities.length === 0) return [];
|
||||
|
||||
const target = capacities[0];
|
||||
const remaining = capacities.slice(1);
|
||||
const remainingSum = remaining.reduce((a, b) => a + b, 0);
|
||||
|
||||
// Available sum check
|
||||
let availSum = 0;
|
||||
for (let i = 0; i < available.length; i++) {
|
||||
if (!usedSet.has(i)) availSum += available[i];
|
||||
}
|
||||
if (availSum < target + remainingSum) return null;
|
||||
|
||||
// Find all subsets summing to target using DFS
|
||||
const subset = [];
|
||||
|
||||
function dfs(startIdx, currentSum) {
|
||||
if (currentSum === target) {
|
||||
// Try solving remaining capacities
|
||||
const newUsed = new Set(usedSet);
|
||||
for (const idx of subset) newUsed.add(idx);
|
||||
const result = findPartition(available, remaining, newUsed);
|
||||
if (result !== null) {
|
||||
return [subset.slice(), ...result];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (currentSum > target) return null;
|
||||
|
||||
for (let i = startIdx; i < available.length; i++) {
|
||||
if (usedSet.has(i)) continue;
|
||||
if (currentSum + available[i] > target) continue;
|
||||
|
||||
// Pruning: check if remaining available sum can reach target
|
||||
let futureSum = 0;
|
||||
for (let j = i; j < available.length; j++) {
|
||||
if (!usedSet.has(j) && !subset.includes(j)) futureSum += available[j];
|
||||
}
|
||||
if (currentSum + futureSum < target) return null;
|
||||
|
||||
subset.push(i);
|
||||
const result = dfs(i + 1, currentSum + available[i]);
|
||||
if (result) return result;
|
||||
subset.pop();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return dfs(0, 0);
|
||||
}
|
||||
|
||||
// Sort ships descending for better pruning (hardest to fill first)
|
||||
const sortedShips = [...ships].sort((a, b) => b - a);
|
||||
|
||||
console.log(`\nSolving for ships (sorted desc): [${sortedShips.join(', ')}]`);
|
||||
|
||||
const solution = findPartition(asteroids, sortedShips);
|
||||
|
||||
if (solution) {
|
||||
console.log('\n✓ SOLVABLE! Solution found:');
|
||||
// Map back to original ship order
|
||||
const shipOrder = ships.map((cap, idx) => ({ cap, idx }))
|
||||
.sort((a, b) => b.cap - a.cap);
|
||||
|
||||
for (let i = 0; i < sortedShips.length; i++) {
|
||||
const indices = solution[i];
|
||||
const values = indices.map(j => asteroids[j]);
|
||||
const origShipIdx = shipOrder[i].idx;
|
||||
console.log(` Ship ${origShipIdx + 1} (capacity ${sortedShips[i]}): asteroids [${values.join(' + ')}] = ${values.reduce((a, b) => a + b, 0)} (indices: ${indices.join(',')})`);
|
||||
}
|
||||
|
||||
const usedIndices = new Set(solution.flat());
|
||||
const unused = asteroids.map((v, i) => ({ v, i })).filter(x => !usedIndices.has(x.i));
|
||||
if (unused.length > 0) {
|
||||
console.log(` Unused asteroids: [${unused.map(x => `${x.v}(idx ${x.i})`).join(', ')}]`);
|
||||
}
|
||||
} else {
|
||||
console.log('\n✗ NO SOLUTION found.');
|
||||
console.log(` Ship sum: ${ships.reduce((a, b) => a + b, 0)}, Asteroid sum: ${asteroids.reduce((a, b) => a + b, 0)}`);
|
||||
if (asteroids.reduce((a, b) => a + b, 0) < ships.reduce((a, b) => a + b, 0)) {
|
||||
console.log(' Reason: asteroid sum < ship sum (mathematically impossible)');
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"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] }
|
||||
},
|
||||
"problemCount": 20,
|
||||
"layout": {
|
||||
"columns": 2,
|
||||
"problemsPerPage": 20
|
||||
},
|
||||
"labels": {
|
||||
"title": "Умножение",
|
||||
"subtitle": "Реши примеры",
|
||||
"name": "Имя: _______________",
|
||||
"date": "Дата: _______________"
|
||||
},
|
||||
"theme": {
|
||||
"background": null,
|
||||
"icons": null,
|
||||
"iconReward": 5
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Math Tasks — Документы</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: 'Nunito', sans-serif;
|
||||
background: #f5f3ff;
|
||||
color: #1e1b4b;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 60px 24px;
|
||||
}
|
||||
h1 { font-size: 2rem; font-weight: 700; margin-bottom: 8px; }
|
||||
.subtitle { color: #6366f1; font-size: 1.05rem; margin-bottom: 48px; }
|
||||
h2 {
|
||||
font-size: 1.3rem; font-weight: 700;
|
||||
margin: 32px 0 12px; width: 100%; max-width: 720px;
|
||||
border-bottom: 2px solid #e0e7ff; padding-bottom: 6px;
|
||||
}
|
||||
.cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 16px;
|
||||
width: 100%; max-width: 720px;
|
||||
}
|
||||
.card {
|
||||
background: white;
|
||||
border: 1px solid #e0e7ff;
|
||||
border-radius: 12px;
|
||||
padding: 20px 24px;
|
||||
color: #1e1b4b;
|
||||
}
|
||||
.card-title { font-weight: 600; font-size: 1.1rem; margin-bottom: 8px; }
|
||||
.card-links { display: flex; gap: 12px; }
|
||||
.card-links a {
|
||||
font-size: 0.88rem; font-weight: 600;
|
||||
text-decoration: none; color: #6366f1;
|
||||
padding: 4px 12px; border-radius: 6px;
|
||||
border: 1px solid #e0e7ff;
|
||||
transition: background 0.15s, border-color 0.15s;
|
||||
}
|
||||
.card-links a:hover {
|
||||
background: #f5f3ff; border-color: #a5b4fc;
|
||||
}
|
||||
.card-links a.edit {
|
||||
color: #059669; border-color: #d1fae5;
|
||||
}
|
||||
.card-links a.edit:hover {
|
||||
background: #ecfdf5; border-color: #6ee7b7;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Math Tasks</h1>
|
||||
<p class="subtitle">Документы для предпросмотра</p>
|
||||
|
||||
<!-- Space Exploration -->
|
||||
<h2>Исследуй Планету</h2>
|
||||
<div class="cards">
|
||||
<div class="card">
|
||||
<div class="card-title">Space Exploration 1 (3 pages)</div>
|
||||
<div class="card-links">
|
||||
<a href="/tasks/space-exploration/docs/space-exploration-1.template.html">View</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-title">Space Worksheet 2 (3 pages)</div>
|
||||
<div class="card-links">
|
||||
<a href="/tasks/space-exploration/docs/space-worksheet2.template.html">View</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-title">Space Worksheet 3 (9 pages)</div>
|
||||
<div class="card-links">
|
||||
<a href="/tasks/space-exploration/docs/space-worksheet3.template.html">View</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Collecting Asteroids -->
|
||||
<h2>Собери Астероиды</h2>
|
||||
<div class="cards">
|
||||
<div class="card">
|
||||
<div class="card-title">Collecting Asteroids 1</div>
|
||||
<div class="card-links">
|
||||
<a href="/tasks/collecting-asteroids/docs/collecting-asteroids-1.template.html">View</a>
|
||||
<a class="edit" href="/tasks/collecting-asteroids/editor.html?file=collecting-asteroids-1">Edit</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-title">Collecting Asteroids 2</div>
|
||||
<div class="card-links">
|
||||
<a href="/tasks/collecting-asteroids/docs/collecting-asteroids-2.template.html">View</a>
|
||||
<a class="edit" href="/tasks/collecting-asteroids/editor.html?file=collecting-asteroids-2">Edit</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-title">Collecting Asteroids 3</div>
|
||||
<div class="card-links">
|
||||
<a href="/tasks/collecting-asteroids/docs/collecting-asteroids-3.template.html">View</a>
|
||||
<a class="edit" href="/tasks/collecting-asteroids/editor.html?file=collecting-asteroids-3">Edit</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Space Route -->
|
||||
<h2>Проложи Маршрут</h2>
|
||||
<div class="cards">
|
||||
<div class="card">
|
||||
<div class="card-title">Space Route 1</div>
|
||||
<div class="card-links">
|
||||
<a href="/tasks/space-route/docs/space-route-1.template.html">View</a>
|
||||
<a class="edit" href="/tasks/space-route/editor.html?file=space-route-1">Edit</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,42 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
# Space Exploration Task Type
|
||||
|
||||
Math problem worksheets with space theme: hero images, footer panoramas, icon-decorated problem cards.
|
||||
|
||||
## Base References
|
||||
|
||||
- Base template: `src/templates/space-base.html` (layout/styling reference)
|
||||
- Example outputs in `docs/` (existing worksheets serve as reference for new ones)
|
||||
|
||||
## What to Vary Per Worksheet
|
||||
|
||||
1. **Hero image** — from `assets/hero-images/spaceship{1-9}.jpeg`
|
||||
2. **Footer image** — from `assets/footers/planet{1-9}.jpeg`
|
||||
3. **Hero position** — `flex-row-reverse` (hero right) or default (hero left)
|
||||
4. **Problem icons** — from `assets/icons/pack1/` or `pack2/`. **Every icon must be unique across the entire document** (no repeats across pages). Shuffle minerals and plants randomly — do not sort by type
|
||||
5. **Problem alignment** — randomly assign `justify-start`, `justify-center`, or `justify-end` per card. No patterns — should look chaotic/scattered
|
||||
6. **Problems** — generate from the task description in the `.md` file
|
||||
|
||||
## Layout Structure (do not change)
|
||||
|
||||
- Page: `w-[210mm] h-[297mm]` white container
|
||||
- Footer: absolute bottom, `h-[80mm]`, with white-to-transparent fade on top. **No `overflow-hidden`** on footer (causes 1px hairline artifact in PDF)
|
||||
- Footer bubble: absolute `bottom-[12mm]`, pill-shaped with semi-transparent white bg
|
||||
- Content area: `px-[12mm] pt-[4mm] pb-[65mm]` flex column
|
||||
- Header: hero image `w-[48%]` + title block centered, `flex-row-reverse` for hero-right
|
||||
- Footer gradient: `linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%)` with `h-full`
|
||||
- Problems: `grid grid-cols-2 gap-x-3 gap-y-[3px]` — 20 problems total
|
||||
- Each problem: 58px icon outside pill + `text-[1.2rem]` expression + `w-16` answer underline inside pill
|
||||
- Font: Nunito via Google Fonts
|
||||
- Uses Tailwind CDN
|
||||
|
||||
## Color Palette (do not change)
|
||||
|
||||
| Element | Hex |
|
||||
|---------|-----|
|
||||
| Title text | `text-indigo-950` (#1e1b4b) |
|
||||
| Subtitle | `text-indigo-400` (#6366f1) |
|
||||
| Card border | `border-indigo-100` (#e0e7ff) |
|
||||
| Answer underline | `border-indigo-300` (#a5b4fc) |
|
||||
| Card bg gradient | `from-white to-indigo-50/40` |
|
||||
| Footer bubble border | `border-indigo-200` |
|
||||
|
||||
## Scripts
|
||||
|
||||
- `scripts/generate-worksheet3.mjs` — generator for 9-page combined worksheets
|
||||
@@ -0,0 +1,200 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<title>Исследуй Планету</title>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: { nunito: ['Nunito', 'sans-serif'] },
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@page { size: A4; margin: 0; }
|
||||
:root {
|
||||
--hero-direction: row-reverse;
|
||||
}
|
||||
.page-header { flex-direction: var(--hero-direction); }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-200 font-nunito">
|
||||
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white">
|
||||
|
||||
<div class="absolute bottom-0 left-0 right-0 h-[80mm] overflow-hidden z-0">
|
||||
<div class="absolute top-0 left-0 right-0 h-[40%] bg-gradient-to-b from-white to-transparent z-10"></div>
|
||||
<img src="../../assets/footers/planet1.jpeg" class="w-full h-full object-cover object-top" alt="">
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-[12mm] left-0 right-0 z-20 flex justify-center">
|
||||
<div style="background: rgba(255,255,255,0.85);" class="rounded-full px-6 py-1.5 border-[1.5px] border-indigo-200 shadow-md">
|
||||
<span class="text-[0.95rem] font-bold text-indigo-950">Итого собрано на планете: <span class="inline-block w-14 border-b-2 border-indigo-400 text-center ml-1"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[8mm] pb-[65mm] flex flex-col">
|
||||
|
||||
<div class="page-header flex items-center gap-4 mb-4">
|
||||
<img src="../../assets/hero-images/spaceship1.jpeg" class="w-[48%] shrink-0 object-contain" alt="">
|
||||
<div class="flex-1 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Исследуй Планету</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-1">Собери ресурсы, решая примеры!</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-3 gap-y-[8px] flex-1 content-start">
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/minerals1-0-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 3 + 8 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/plants1-0-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">7 × 4 − 6 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/minerals3-1-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 6 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/plants2-0-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">8 × 2 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/minerals2-0-1.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 5 − 7 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/minerals5-0-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">6 × 3 + 9 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/plants1-1-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">9 × 2 − 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/minerals4-0-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">7 × 3 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/plants3-0-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 8 + 6 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/minerals6-0-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 4 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/minerals1-2-1.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 7 + 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/plants1-3-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">9 × 3 − 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/minerals1-1-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 6 + 7 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/plants2-1-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">8 × 3 − 9 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/minerals2-1-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">6 × 4 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/plants3-1-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">7 × 2 + 8 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/minerals3-0-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 9 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/minerals5-1-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 5 + 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/plants1-2-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 8 − 6 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[3px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit">
|
||||
<img src="../../assets/icons/pack1/minerals4-1-0.png" class="w-11 h-11 shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 7 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,537 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<title>Исследуй Планету</title>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: { nunito: ['Nunito', 'sans-serif'] },
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@page { size: A4; margin: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-200 font-nunito">
|
||||
|
||||
<!-- PAGE 1: A + B ± C (A:8-16, B:4-8, C:±1-3) — hero right, spaceship2, planet3 -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
|
||||
<div class="absolute bottom-0 left-0 right-0 h-[80mm] z-0">
|
||||
<div class="absolute top-0 left-0 right-0 h-full z-10" style="background: linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%);"></div>
|
||||
<img src="../../assets/footers/planet3.jpeg" class="w-full h-full object-cover object-top" alt="">
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-[12mm] left-0 right-0 z-20 flex justify-center">
|
||||
<div style="background: rgba(255,255,255,0.85);" class="rounded-full px-6 py-1.5 border-[1.5px] border-indigo-200 shadow-md">
|
||||
<span class="text-[0.95rem] font-bold text-indigo-950">Итого собрано на планете: <span class="inline-block w-14 border-b-2 border-indigo-400 text-center ml-1"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[4mm] pb-[65mm] flex flex-col">
|
||||
|
||||
<div class="flex items-center gap-4 mb-4 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/spaceship2.jpeg" class="w-[48%] shrink-0 object-contain" alt="">
|
||||
<div class="flex-1 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Исследуй Планету</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-1">Собери ресурсы, решая примеры!</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-3 gap-y-[8px] flex-1 content-start">
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants1-2-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">12 + 7 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals4-0-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">9 + 5 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants5-1-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">14 + 6 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals3-2-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">11 + 4 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals2-3-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">8 + 8 + 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants3-3-2.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">15 + 5 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants6-3-2.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">10 + 7 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals3-2-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">13 + 4 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants1-1-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">16 + 6 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants6-0-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">9 + 8 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals5-2-2.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">11 + 5 + 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants5-3-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">14 + 7 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants3-1-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">8 + 6 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants3-0-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">12 + 4 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants1-2-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">15 + 8 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants3-1-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">10 + 5 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants4-2-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">13 + 7 + 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants3-2-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">16 + 4 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants1-0-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">9 + 6 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals2-3-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">11 + 8 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 2: 5 × N ± C (N:1-5, C:-3..+6) — hero left, spaceship4, planet5 -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
|
||||
<div class="absolute bottom-0 left-0 right-0 h-[80mm] z-0">
|
||||
<div class="absolute top-0 left-0 right-0 h-full z-10" style="background: linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%);"></div>
|
||||
<img src="../../assets/footers/planet5.jpeg" class="w-full h-full object-cover object-top" alt="">
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-[12mm] left-0 right-0 z-20 flex justify-center">
|
||||
<div style="background: rgba(255,255,255,0.85);" class="rounded-full px-6 py-1.5 border-[1.5px] border-indigo-200 shadow-md">
|
||||
<span class="text-[0.95rem] font-bold text-indigo-950">Итого собрано на планете: <span class="inline-block w-14 border-b-2 border-indigo-400 text-center ml-1"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[4mm] pb-[65mm] flex flex-col">
|
||||
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<img src="../../assets/hero-images/spaceship4.jpeg" class="w-[48%] shrink-0 object-contain" alt="">
|
||||
<div class="flex-1 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Исследуй Планету</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-1">Собери ресурсы, решая примеры!</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-3 gap-y-[8px] flex-1 content-start">
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals4-3-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 3 + 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals1-2-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 1 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals5-3-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 5 + 6 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants2-1-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 2 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals6-1-2.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 4 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals5-3-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 1 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants2-1-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 3 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals5-0-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 5 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals1-3-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 2 + 6 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals4-1-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 4 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals1-0-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 1 + 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants4-3-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 3 + 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants4-3-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 5 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants4-3-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 2 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals6-0-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 4 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals4-0-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 1 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals4-2-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 3 + 6 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants2-3-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 2 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals3-1-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 5 + 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals2-0-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 4 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 3: A × B ± C (A,B:1-4, C:-4..+8) — hero right, spaceship6, planet1 -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white">
|
||||
|
||||
<div class="absolute bottom-0 left-0 right-0 h-[80mm] z-0">
|
||||
<div class="absolute top-0 left-0 right-0 h-full z-10" style="background: linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%);"></div>
|
||||
<img src="../../assets/footers/planet1.jpeg" class="w-full h-full object-cover object-top" alt="">
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-[12mm] left-0 right-0 z-20 flex justify-center">
|
||||
<div style="background: rgba(255,255,255,0.85);" class="rounded-full px-6 py-1.5 border-[1.5px] border-indigo-200 shadow-md">
|
||||
<span class="text-[0.95rem] font-bold text-indigo-950">Итого собрано на планете: <span class="inline-block w-14 border-b-2 border-indigo-400 text-center ml-1"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[4mm] pb-[65mm] flex flex-col">
|
||||
|
||||
<div class="flex items-center gap-4 mb-4 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/spaceship6.jpeg" class="w-[48%] shrink-0 object-contain" alt="">
|
||||
<div class="flex-1 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Исследуй Планету</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-1">Собери ресурсы, решая примеры!</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-3 gap-y-[8px] flex-1 content-start">
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants6-0-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 4 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals6-2-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 3 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals4-1-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 4 + 7 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants6-1-2.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">1 × 3 + 6 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals2-2-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 2 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants1-0-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 3 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals1-3-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 4 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants5-2-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">1 × 4 + 8 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants2-2-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 3 − 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants4-0-2.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 2 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals4-1-2.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 2 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals5-1-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">1 × 2 + 7 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants4-0-1.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 4 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals3-3-2.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 1 + 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals6-0-2.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 3 + 6 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants5-1-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 1 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants1-3-2.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 4 + 8 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants4-2-2.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">1 × 3 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/minerals5-2-0.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 4 + 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center py-[3px]">
|
||||
<div class="flex items-center gap-1.5 pl-0.5 pr-4 py-[1px] border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30 w-fit overflow-hidden">
|
||||
<img src="../../assets/icons/pack1/plants3-0-3.png" class="w-[39px] h-[39px] shrink-0 object-contain" alt="">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 3 − 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,27 @@
|
||||
# Space Exploration 1
|
||||
|
||||
**Title:** Исследуй Планету
|
||||
**Subtitle:** Собери ресурсы, решая примеры!
|
||||
**Footer bubble:** Итого собрано на планете:
|
||||
|
||||
## Layout
|
||||
|
||||
- 2 columns, 20 problems per page
|
||||
- Icons: assets/icons/pack1/
|
||||
|
||||
## Pages
|
||||
|
||||
### Page 1
|
||||
- **Task:** A + B +/- C, where A from 8 to 16, B from 4 to 8, C from 1 to 3. Sign +/- chosen randomly
|
||||
- **Problem count:** 20
|
||||
- **Hero:** spaceship2.jpeg, direction: row-reverse
|
||||
|
||||
### Page 2
|
||||
- **Task:** 5 * N +/- C, where N from 1 to 5, C from 1 to 6. Sign +/- chosen randomly
|
||||
- **Problem count:** 20
|
||||
- **Hero:** spaceship4.jpeg, direction: row
|
||||
|
||||
### Page 3
|
||||
- **Task:** A * B +/- C, where A and B from 1 to 4, C from 1 to 8. Sign +/- chosen randomly
|
||||
- **Problem count:** 20
|
||||
- **Hero:** spaceship6.jpeg, direction: row-reverse
|
||||
@@ -0,0 +1,657 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<title>Исследуй Планету</title>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: { nunito: ['Nunito', 'sans-serif'] },
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@page { size: A4; margin: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-200 font-nunito">
|
||||
|
||||
<!-- PAGE 1: A + B ± C (A:8-16, B:4-8, C:±1-3) — hero right, spaceship2, planet3 -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
|
||||
<div class="absolute bottom-0 left-0 right-0 h-[80mm] z-0">
|
||||
<div class="absolute top-0 left-0 right-0 h-full z-10" style="background: linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%);"></div>
|
||||
<img src="../../assets/footers/planet3.jpeg" class="w-full h-full object-cover object-top" alt="">
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-[12mm] left-0 right-0 z-20 flex justify-center">
|
||||
<div style="background: rgba(255,255,255,0.85);" class="rounded-full px-6 py-1.5 border-[1.5px] border-indigo-200 shadow-md">
|
||||
<span class="text-[0.95rem] font-bold text-indigo-950">Итого собрано на планете: <span class="inline-block w-14 border-b-2 border-indigo-400 text-center ml-1"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[4mm] pb-[65mm] flex flex-col">
|
||||
|
||||
<div class="flex items-center gap-4 mb-4 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/spaceship2.png" class="w-[48%] shrink-0 object-contain" alt="">
|
||||
<div class="flex-1 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Исследуй Планету</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-1">Собери ресурсы, решая примеры!</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-3 gap-y-[3px] flex-1 content-start">
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants1-2-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">12 + 7 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals4-0-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">9 + 5 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants5-1-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">14 + 6 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals3-2-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">11 + 4 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals2-3-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">8 + 8 + 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants3-3-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">15 + 5 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants6-3-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">10 + 7 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals3-2-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">13 + 4 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants1-1-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">16 + 6 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants6-0-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">9 + 8 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals5-2-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">11 + 5 + 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants5-3-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">14 + 7 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants3-1-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">8 + 6 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants3-0-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">12 + 4 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants1-2-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">15 + 8 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants3-1-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">10 + 5 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants4-2-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">13 + 7 + 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants3-2-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">16 + 4 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants1-0-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">9 + 6 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals2-3-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">11 + 8 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 2: 5 × N ± C (N:1-5, C:-3..+6) — hero left, spaceship4, planet5 -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
|
||||
<div class="absolute bottom-0 left-0 right-0 h-[80mm] z-0">
|
||||
<div class="absolute top-0 left-0 right-0 h-full z-10" style="background: linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%);"></div>
|
||||
<img src="../../assets/footers/planet5.jpeg" class="w-full h-full object-cover object-top" alt="">
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-[12mm] left-0 right-0 z-20 flex justify-center">
|
||||
<div style="background: rgba(255,255,255,0.85);" class="rounded-full px-6 py-1.5 border-[1.5px] border-indigo-200 shadow-md">
|
||||
<span class="text-[0.95rem] font-bold text-indigo-950">Итого собрано на планете: <span class="inline-block w-14 border-b-2 border-indigo-400 text-center ml-1"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[4mm] pb-[65mm] flex flex-col">
|
||||
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<img src="../../assets/hero-images/spaceship4.jpeg" class="w-[48%] shrink-0 object-contain" alt="">
|
||||
<div class="flex-1 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Исследуй Планету</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-1">Собери ресурсы, решая примеры!</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-3 gap-y-[3px] flex-1 content-start">
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals4-3-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 3 + 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals1-2-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 1 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals5-3-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 5 + 6 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants2-1-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 2 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals6-1-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 4 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals5-3-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 1 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants2-1-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 3 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals5-0-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 5 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals1-3-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 2 + 6 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals4-1-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 4 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals1-0-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 1 + 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants4-3-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 3 + 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants4-3-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 5 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants4-3-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 2 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals6-0-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 4 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals4-0-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 1 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals4-2-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 3 + 6 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants2-3-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 2 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals3-1-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 5 + 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals2-0-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 4 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 3: A × B ± C (A,B:1-4, C:-4..+8) — hero right, spaceship6, planet1 -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white">
|
||||
|
||||
<div class="absolute bottom-0 left-0 right-0 h-[80mm] z-0">
|
||||
<div class="absolute top-0 left-0 right-0 h-full z-10" style="background: linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%);"></div>
|
||||
<img src="../../assets/footers/planet1.jpeg" class="w-full h-full object-cover object-top" alt="">
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-[12mm] left-0 right-0 z-20 flex justify-center">
|
||||
<div style="background: rgba(255,255,255,0.85);" class="rounded-full px-6 py-1.5 border-[1.5px] border-indigo-200 shadow-md">
|
||||
<span class="text-[0.95rem] font-bold text-indigo-950">Итого собрано на планете: <span class="inline-block w-14 border-b-2 border-indigo-400 text-center ml-1"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[4mm] pb-[65mm] flex flex-col">
|
||||
|
||||
<div class="flex items-center gap-4 mb-4 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/spaceship6.jpeg" class="w-[48%] shrink-0 object-contain" alt="">
|
||||
<div class="flex-1 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Исследуй Планету</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-1">Собери ресурсы, решая примеры!</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-3 gap-y-[3px] flex-1 content-start">
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants6-0-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 4 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals6-2-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 3 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals4-1-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 4 + 7 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants6-1-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">1 × 3 + 6 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals2-2-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 2 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants1-0-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 3 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals1-3-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 4 − 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants5-2-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">1 × 4 + 8 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants2-2-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 3 − 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants4-0-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 2 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals4-1-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 2 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals5-1-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">1 × 2 + 7 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants4-0-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 4 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals3-3-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 1 + 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals6-0-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 3 + 6 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants5-1-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 1 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants1-3-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 4 + 8 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants4-2-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">1 × 3 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/minerals5-2-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 4 + 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack1/plants3-0-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 3 − 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,659 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<title>Исследуй Планету</title>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: { nunito: ['Nunito', 'sans-serif'] },
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@page { size: A4; margin: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-200 font-nunito">
|
||||
|
||||
<!-- PAGE 1: A + B + C (A:12-24, B:±6-10, C:±2-5, result 0-40) — hero right, spaceship1, planet2 -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
|
||||
<div class="absolute bottom-0 left-0 right-0 h-[80mm] z-0">
|
||||
<div class="absolute top-0 left-0 right-0 h-full z-10" style="background: linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%);"></div>
|
||||
<img src="../../assets/footers/planet2.jpeg" class="w-full h-full object-cover object-top" alt="">
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-[12mm] left-0 right-0 z-20 flex justify-center">
|
||||
<div style="background: rgba(255,255,255,0.85);" class="rounded-full px-6 py-1.5 border-[1.5px] border-indigo-200 shadow-md">
|
||||
<span class="text-[0.95rem] font-bold text-indigo-950">Итого собрано на планете: <span class="inline-block w-14 border-b-2 border-indigo-400 text-center ml-1"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[4mm] pb-[65mm] flex flex-col">
|
||||
|
||||
<div class="flex items-center gap-4 mb-4 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/spaceship1.jpeg" class="w-[48%] shrink-0 object-contain" alt="">
|
||||
<div class="flex-1 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Исследуй Планету</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-1">Собери ресурсы, решая примеры!</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-3 gap-y-[3px] flex-1 content-start">
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-2-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">18 + 7 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-0-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">15 − 9 + 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem4-1-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">22 + 6 − 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-3-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">12 − 8 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-2-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">20 + 10 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-0-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">16 − 7 − 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem4-2-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">24 + 8 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-1-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">14 − 6 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-3-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">19 + 9 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-1-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">13 − 10 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-0-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">21 + 7 + 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem4-0-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">17 − 8 − 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-1-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">23 + 6 − 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-3-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">12 + 10 − 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-2-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">15 + 9 + 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem4-1-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">20 − 7 + 3 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-0-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">24 − 6 − 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-2-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">18 + 8 − 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-3-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">14 + 10 + 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem4-0-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">16 − 9 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 2: 5+5+5 / 5×N / 5×N±5 — hero left, spaceship3, planet4 -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="break-after: page;">
|
||||
|
||||
<div class="absolute bottom-0 left-0 right-0 h-[80mm] z-0">
|
||||
<div class="absolute top-0 left-0 right-0 h-full z-10" style="background: linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%);"></div>
|
||||
<img src="../../assets/footers/planet4.jpeg" class="w-full h-full object-cover object-top" alt="">
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-[12mm] left-0 right-0 z-20 flex justify-center">
|
||||
<div style="background: rgba(255,255,255,0.85);" class="rounded-full px-6 py-1.5 border-[1.5px] border-indigo-200 shadow-md">
|
||||
<span class="text-[0.95rem] font-bold text-indigo-950">Итого собрано на планете: <span class="inline-block w-14 border-b-2 border-indigo-400 text-center ml-1"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[4mm] pb-[65mm] flex flex-col">
|
||||
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<img src="../../assets/hero-images/spaceship3.png" class="w-[48%] shrink-0 object-contain" alt="">
|
||||
<div class="flex-1 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Исследуй Планету</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-1">Собери ресурсы, решая примеры!</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="font-semibold text-indigo-950 mb-3 text-center" style="font-size: 0.8rem; margin-top: -10px;">Посчитай пятёрками: <span style="font-size: 1rem; word-spacing: 0.25em;">5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60</span> для зарядки расщепителя</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-3 gap-y-[3px] flex-1 content-start">
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-0-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 + 5 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem4-2-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 7 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-3-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 3 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-0-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-1-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 11 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem4-0-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 5 − 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-1-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 + 5 + 5 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-3-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 9 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-2-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 6 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem4-1-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-0-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 8 − 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-1-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 4 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-3-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 10 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem4-2-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 + 5 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-2-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 12 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-0-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 3 − 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-0-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem4-1-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 7 − 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-3-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 8 + 5 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-2-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">5 × 6 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PAGE 3: A×B + C×D (A:2-4, B:1-3, C:2-3, D:1-2) — hero right, spaceship5, planet6 -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white">
|
||||
|
||||
<div class="absolute bottom-0 left-0 right-0 h-[80mm] z-0">
|
||||
<div class="absolute top-0 left-0 right-0 h-full z-10" style="background: linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%);"></div>
|
||||
<img src="../../assets/footers/planet6.jpeg" class="w-full h-full object-cover object-top" alt="">
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-[12mm] left-0 right-0 z-20 flex justify-center">
|
||||
<div style="background: rgba(255,255,255,0.85);" class="rounded-full px-6 py-1.5 border-[1.5px] border-indigo-200 shadow-md">
|
||||
<span class="text-[0.95rem] font-bold text-indigo-950">Итого собрано на планете: <span class="inline-block w-14 border-b-2 border-indigo-400 text-center ml-1"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[4mm] pb-[65mm] flex flex-col">
|
||||
|
||||
<div class="flex items-center gap-4 mb-4 flex-row-reverse">
|
||||
<img src="../../assets/hero-images/spaceship5.jpeg" class="w-[48%] shrink-0 object-contain" alt="">
|
||||
<div class="flex-1 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Исследуй Планету</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-1">Собери ресурсы, решая примеры!</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-3 gap-y-[3px] flex-1 content-start">
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-1-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 2 + 2 × 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem4-0-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 3 + 3 × 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-2-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 1 + 3 × 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-1-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 2 + 2 × 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-2-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 3 + 2 × 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem4-2-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 3 + 3 × 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-0-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 1 + 2 × 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-3-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 1 + 3 × 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-0-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 3 + 2 × 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-3-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 2 + 3 × 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-1-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 3 + 3 × 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-0-0.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 1 + 2 × 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-3-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 3 + 2 × 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-2-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 2 + 3 × 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-3-1.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 1 + 2 × 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem3-1-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 3 + 3 × 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-2-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 1 + 2 × 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-2-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">3 × 2 + 3 × 2 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem2-1-2.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">4 × 2 + 2 × 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../assets/icons/pack2/elem1-1-3.png" class="w-[58px] h-[58px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">2 × 2 + 3 × 1 = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,27 @@
|
||||
# Space Worksheet 2
|
||||
|
||||
**Title:** Исследуй Планету
|
||||
**Subtitle:** Собери ресурсы, ре��ая примеры!
|
||||
**Footer bubble:** Итого собрано на планете:
|
||||
|
||||
## Layout
|
||||
|
||||
- 2 columns, 20 problems per page
|
||||
- Icons: assets/icons/pack2/
|
||||
|
||||
## Pages
|
||||
|
||||
### Page 1
|
||||
- **Task:** A + B + C, where A from 12 to 24, B +/-(from 6 to 10), C +/-(from 2 to 5). Result from 0 to 40 inclusive
|
||||
- **Problem count:** 20
|
||||
- **Hero:** spaceship1.jpeg, direction: row-reverse
|
||||
|
||||
### Page 2
|
||||
- **Task:** 5 + 5 + 5 (adding fives: 2, 3 or 4 of them) OR 5 * N (N from 1 to 12) OR 5 * N +/- 5
|
||||
- **Problem count:** 20
|
||||
- **Hero:** spaceship3.png, direction: row
|
||||
|
||||
### Page 3
|
||||
- **Task:** A * B + C * D, where A from 2 to 4, B from 1 to 3, C from 2 to 3, D from 1 to 2
|
||||
- **Problem count:** 20
|
||||
- **Hero:** spaceship5.jpeg, direction: row-reverse
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,53 @@
|
||||
# Space Worksheet 3
|
||||
|
||||
**Title:** Исследуй Планету
|
||||
**Subtitle:** Собери ресу��сы, решая примеры!
|
||||
**Footer bubble:** Итого собрано на планете:
|
||||
|
||||
## Layout
|
||||
|
||||
- 2 columns, 20 problems per page
|
||||
- Icons: mixed from pack1 and pack2
|
||||
|
||||
## Notes
|
||||
|
||||
9-page worksheet combining patterns from worksheet1 and worksheet2.
|
||||
Pages 1-3 use pack1 icons, pages 4-6 use pack2 icons, pages 7-9 use pack1 icons.
|
||||
|
||||
## Pages
|
||||
|
||||
### Page 1 (pack1)
|
||||
- **Task:** A + B +/- C, where A from 8 to 16, B from 4 to 8, C from 1 to 3. Sign +/- chosen randomly
|
||||
- **Hero:** spaceship1.jpeg, direction: row-reverse
|
||||
|
||||
### Page 2 (pack1)
|
||||
- **Task:** 5 * N +/- C, where N from 1 to 5, C from 1 to 6. Sign +/- chosen randomly
|
||||
- **Hero:** spaceship2.jpeg, direction: row
|
||||
|
||||
### Page 3 (pack1)
|
||||
- **Task:** A * B +/- C, where A and B from 1 to 4, C from 1 to 8. Sign +/- chosen randomly
|
||||
- **Hero:** spaceship3.png, direction: row-reverse
|
||||
|
||||
### Page 4 (pack2)
|
||||
- **Task:** A + B + C, where A from 12 to 24, B +/-(from 6 to 10), C +/-(from 2 to 5). Result from 0 to 40 inclusive
|
||||
- **Hero:** spaceship4.jpeg, direction: row
|
||||
|
||||
### Page 5 (pack2)
|
||||
- **Task:** 5 + 5 + 5 (adding fives: 2, 3 or 4) OR 5 * N (N from 1 to 12) OR 5 * N +/- 5
|
||||
- **Hero:** spaceship5.jpeg, direction: row-reverse
|
||||
|
||||
### Page 6 (pack2)
|
||||
- **Task:** A * B + C * D, where A from 2 to 4, B from 1 to 3, C from 2 to 3, D from 1 to 2
|
||||
- **Hero:** spaceship6.jpeg, direction: row
|
||||
|
||||
### Page 7 (pack1)
|
||||
- **Task:** A + B +/- C, where A from 8 to 16, B from 4 to 8, C from 1 to 3. Sign +/- chosen randomly
|
||||
- **Hero:** spaceship7.jpeg, direction: row-reverse
|
||||
|
||||
### Page 8 (pack1)
|
||||
- **Task:** 5 * N +/- C, where N from 1 to 5, C from 1 to 6. Sign +/- chosen randomly
|
||||
- **Hero:** spaceship8.jpeg, direction: row
|
||||
|
||||
### Page 9 (pack1)
|
||||
- **Task:** A * B +/- C, where A and B from 1 to 4, C from 1 to 8. Sign +/- chosen randomly
|
||||
- **Hero:** spaceship9.jpeg, direction: row-reverse
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,311 @@
|
||||
/**
|
||||
* Generate space-worksheet3.html — 9-page static HTML worksheet
|
||||
* combining task patterns from worksheet1 and worksheet2.
|
||||
*
|
||||
* Usage: node src/scripts/generate-worksheet3.mjs
|
||||
* Output: output/html/space-worksheet3.html
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const ROOT = process.cwd();
|
||||
|
||||
// ── Icon pools ──────────────────────────────────────────────────────────────
|
||||
const pack1Icons = fs.readdirSync(path.join(ROOT, 'assets/icons/pack1'))
|
||||
.filter(f => f.endsWith('.png'))
|
||||
.map(f => `assets/icons/pack1/${f}`);
|
||||
|
||||
const pack2Icons = fs.readdirSync(path.join(ROOT, 'assets/icons/pack2'))
|
||||
.filter(f => f.endsWith('.png'))
|
||||
.map(f => `assets/icons/pack2/${f}`);
|
||||
|
||||
function shuffle(arr) {
|
||||
const a = [...arr];
|
||||
for (let i = a.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[a[i], a[j]] = [a[j], a[i]];
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
function randInt(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
function randSign() {
|
||||
return Math.random() < 0.5 ? 1 : -1;
|
||||
}
|
||||
|
||||
function pickAlignment() {
|
||||
const opts = ['justify-start', 'justify-center', 'justify-end'];
|
||||
return opts[Math.floor(Math.random() * opts.length)];
|
||||
}
|
||||
|
||||
// ── Problem generators ──────────────────────────────────────────────────────
|
||||
|
||||
// Pattern 1: A + B ± C (A:8-16, B:4-8, C:1-3)
|
||||
function genPattern1() {
|
||||
const problems = [];
|
||||
const seen = new Set();
|
||||
while (problems.length < 20) {
|
||||
const A = randInt(8, 16);
|
||||
const B = randInt(4, 8);
|
||||
const C = randInt(1, 3);
|
||||
const sign = randSign();
|
||||
const expr = sign > 0 ? `${A} + ${B} + ${C}` : `${A} + ${B} − ${C}`;
|
||||
const result = A + B + sign * C;
|
||||
if (result >= 0 && !seen.has(expr)) {
|
||||
seen.add(expr);
|
||||
problems.push(expr);
|
||||
}
|
||||
}
|
||||
return problems;
|
||||
}
|
||||
|
||||
// Pattern 2: 5 × N ± C (N:1-5, C:1-6)
|
||||
function genPattern2() {
|
||||
const problems = [];
|
||||
const seen = new Set();
|
||||
while (problems.length < 20) {
|
||||
const N = randInt(1, 5);
|
||||
const C = randInt(1, 6);
|
||||
const sign = randSign();
|
||||
const expr = sign > 0 ? `5 × ${N} + ${C}` : `5 × ${N} − ${C}`;
|
||||
const result = 5 * N + sign * C;
|
||||
if (result >= 0 && !seen.has(expr)) {
|
||||
seen.add(expr);
|
||||
problems.push(expr);
|
||||
}
|
||||
}
|
||||
return problems;
|
||||
}
|
||||
|
||||
// Pattern 3: A × B ± C (A,B:1-4, C:1-8)
|
||||
function genPattern3() {
|
||||
const problems = [];
|
||||
const seen = new Set();
|
||||
while (problems.length < 20) {
|
||||
const A = randInt(1, 4);
|
||||
const B = randInt(1, 4);
|
||||
const C = randInt(1, 8);
|
||||
const sign = randSign();
|
||||
const expr = sign > 0 ? `${A} × ${B} + ${C}` : `${A} × ${B} − ${C}`;
|
||||
const result = A * B + sign * C;
|
||||
if (result >= 0 && !seen.has(expr)) {
|
||||
seen.add(expr);
|
||||
problems.push(expr);
|
||||
}
|
||||
}
|
||||
return problems;
|
||||
}
|
||||
|
||||
// Pattern 4: A + B + C (A:12-24, B:±6-10, C:±2-5, result 0-40)
|
||||
function genPattern4() {
|
||||
const problems = [];
|
||||
const seen = new Set();
|
||||
while (problems.length < 20) {
|
||||
const A = randInt(12, 24);
|
||||
const signB = randSign();
|
||||
const B = randInt(6, 10);
|
||||
const signC = randSign();
|
||||
const C = randInt(2, 5);
|
||||
const result = A + signB * B + signC * C;
|
||||
if (result >= 0 && result <= 40) {
|
||||
const bPart = signB > 0 ? `+ ${B}` : `− ${B}`;
|
||||
const cPart = signC > 0 ? `+ ${C}` : `− ${C}`;
|
||||
const expr = `${A} ${bPart} ${cPart}`;
|
||||
if (!seen.has(expr)) {
|
||||
seen.add(expr);
|
||||
problems.push(expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return problems;
|
||||
}
|
||||
|
||||
// Pattern 5: mixed fives (5+5+5, 5×N, 5×N±5)
|
||||
function genPattern5() {
|
||||
const problems = [];
|
||||
const seen = new Set();
|
||||
|
||||
// Type A: 5+5+5 (2,3,4 fives)
|
||||
for (const count of [2, 3, 4]) {
|
||||
const expr = Array(count).fill('5').join(' + ');
|
||||
problems.push(expr);
|
||||
seen.add(expr);
|
||||
}
|
||||
|
||||
// Type B: 5×N (N:1-12)
|
||||
const ns = shuffle([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
|
||||
for (const n of ns) {
|
||||
if (problems.length >= 20) break;
|
||||
const expr = `5 × ${n}`;
|
||||
if (!seen.has(expr)) {
|
||||
seen.add(expr);
|
||||
problems.push(expr);
|
||||
}
|
||||
}
|
||||
|
||||
// Type C: 5×N±5 (fill remaining)
|
||||
while (problems.length < 20) {
|
||||
const N = randInt(2, 12);
|
||||
const sign = randSign();
|
||||
const expr = sign > 0 ? `5 × ${N} + 5` : `5 × ${N} − 5`;
|
||||
if (!seen.has(expr)) {
|
||||
seen.add(expr);
|
||||
problems.push(expr);
|
||||
}
|
||||
}
|
||||
|
||||
return shuffle(problems);
|
||||
}
|
||||
|
||||
// Pattern 6: A×B + C×D (A:2-4, B:1-3, C:2-3, D:1-2)
|
||||
function genPattern6() {
|
||||
const problems = [];
|
||||
const seen = new Set();
|
||||
while (problems.length < 20) {
|
||||
const A = randInt(2, 4);
|
||||
const B = randInt(1, 3);
|
||||
const C = randInt(2, 3);
|
||||
const D = randInt(1, 2);
|
||||
const expr = `${A} × ${B} + ${C} × ${D}`;
|
||||
if (!seen.has(expr)) {
|
||||
seen.add(expr);
|
||||
problems.push(expr);
|
||||
}
|
||||
}
|
||||
return problems;
|
||||
}
|
||||
|
||||
const generators = [genPattern1, genPattern2, genPattern3, genPattern4, genPattern5, genPattern6, genPattern1, genPattern2, genPattern3];
|
||||
|
||||
// ── Page config ─────────────────────────────────────────────────────────────
|
||||
const pages = [
|
||||
{ hero: 'assets/hero-images/spaceship1.jpeg', footer: 'assets/footers/planet1.jpeg', dir: 'flex-row-reverse', pack: 'pack1', gen: 0 },
|
||||
{ hero: 'assets/hero-images/spaceship2.jpeg', footer: 'assets/footers/planet2.jpeg', dir: '', pack: 'pack1', gen: 1 },
|
||||
{ hero: 'assets/hero-images/spaceship3.png', footer: 'assets/footers/planet3.jpeg', dir: 'flex-row-reverse', pack: 'pack1', gen: 2 },
|
||||
{ hero: 'assets/hero-images/spaceship4.jpeg', footer: 'assets/footers/planet4.jpeg', dir: '', pack: 'pack2', gen: 3 },
|
||||
{ hero: 'assets/hero-images/spaceship5.jpeg', footer: 'assets/footers/planet5.jpeg', dir: 'flex-row-reverse', pack: 'pack2', gen: 4, fivesHint: true },
|
||||
{ hero: 'assets/hero-images/spaceship6.jpeg', footer: 'assets/footers/planet6.jpeg', dir: '', pack: 'pack2', gen: 5 },
|
||||
{ hero: 'assets/hero-images/spaceship7.jpeg', footer: 'assets/footers/planet7.jpeg', dir: 'flex-row-reverse', pack: 'pack1', gen: 6 },
|
||||
{ hero: 'assets/hero-images/spaceship8.jpeg', footer: 'assets/footers/planet8.jpeg', dir: '', pack: 'pack1', gen: 7 },
|
||||
{ hero: 'assets/hero-images/spaceship9.jpeg', footer: 'assets/footers/planet9.jpeg', dir: 'flex-row-reverse', pack: 'pack1', gen: 8 },
|
||||
];
|
||||
|
||||
// ── Assign icons per section (3 pages share a pool) ─────────────────────────
|
||||
// Section 1 (pages 0-2): pack1 shuffled
|
||||
// Section 2 (pages 3-5): pack2 shuffled
|
||||
// Section 3 (pages 6-8): pack1 re-shuffled
|
||||
const iconSections = [
|
||||
shuffle(pack1Icons), // pages 0-2: 60 icons
|
||||
shuffle(pack2Icons), // pages 3-5: 60 icons
|
||||
shuffle(pack1Icons), // pages 6-8: 60 icons (reuse pack1, different shuffle)
|
||||
];
|
||||
|
||||
// ── Build HTML ──────────────────────────────────────────────────────────────
|
||||
function buildProblemCard(icon, expression, alignment, iconSize) {
|
||||
return ` <div class="flex ${alignment}">
|
||||
<div class="flex items-center gap-1">
|
||||
<img src="../../${icon}" class="w-[${iconSize}px] h-[${iconSize}px] shrink-0 object-contain" alt="">
|
||||
<div class="pl-3 pr-4 py-1 border-[1.5px] border-indigo-100 rounded-full bg-gradient-to-br from-white to-indigo-50/40 shadow-sm shadow-indigo-100/30">
|
||||
<span class="text-[1.2rem] font-semibold text-indigo-950 whitespace-nowrap">${expression} = <span class="inline-block w-16 border-b-[2px] border-indigo-300"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function buildPage(pageIdx, isLast) {
|
||||
const pg = pages[pageIdx];
|
||||
const sectionIdx = Math.floor(pageIdx / 3);
|
||||
const posInSection = pageIdx % 3;
|
||||
const sectionIcons = iconSections[sectionIdx];
|
||||
const pageIcons = sectionIcons.slice(posInSection * 20, posInSection * 20 + 20);
|
||||
const iconSize = pg.pack === 'pack2' ? 58 : 58;
|
||||
|
||||
const problems = generators[pg.gen]();
|
||||
const dirClass = pg.dir ? ` ${pg.dir}` : '';
|
||||
const breakStyle = isLast ? '' : ' style="break-after: page;"';
|
||||
|
||||
const fivesHint = pg.fivesHint
|
||||
? `\n <div class="font-semibold text-indigo-950 mb-3 text-center" style="font-size: 0.8rem; margin-top: -10px;">Посчитай пятёрками: <span style="font-size: 1rem; word-spacing: 0.25em;">5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60</span> для зарядки расщепителя</div>\n`
|
||||
: '';
|
||||
|
||||
const cards = problems.map((expr, i) => {
|
||||
return buildProblemCard(pageIcons[i], expr, pickAlignment(), iconSize);
|
||||
}).join('\n\n');
|
||||
|
||||
return ` <!-- PAGE ${pageIdx + 1} -->
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white"${breakStyle}>
|
||||
|
||||
<div class="absolute bottom-0 left-0 right-0 h-[80mm] z-0">
|
||||
<div class="absolute top-0 left-0 right-0 h-full z-10" style="background: linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%);"></div>
|
||||
<img src="../../${pg.footer}" class="w-full h-full object-cover object-top" alt="">
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-[12mm] left-0 right-0 z-20 flex justify-center">
|
||||
<div style="background: rgba(255,255,255,0.85);" class="rounded-full px-6 py-1.5 border-[1.5px] border-indigo-200 shadow-md">
|
||||
<span class="text-[0.95rem] font-bold text-indigo-950">Итого собрано на планете: <span class="inline-block w-14 border-b-2 border-indigo-400 text-center ml-1"> </span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative z-10 w-full h-full px-[12mm] pt-[4mm] pb-[65mm] flex flex-col">
|
||||
|
||||
<div class="flex items-center gap-4 mb-4${dirClass}">
|
||||
<img src="../../${pg.hero}" class="w-[48%] shrink-0 object-contain" alt="">
|
||||
<div class="flex-1 flex flex-col items-center justify-center text-center">
|
||||
<h1 class="text-2xl font-extrabold leading-tight tracking-tight text-indigo-950">Исследуй Планету</h1>
|
||||
<p class="text-sm font-medium text-indigo-400 mt-1">Собери ресурсы, решая примеры!</p>
|
||||
</div>
|
||||
</div>
|
||||
${fivesHint}
|
||||
<div class="grid grid-cols-2 gap-x-3 gap-y-[3px] flex-1 content-start">
|
||||
|
||||
${cards}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
const htmlPages = pages.map((_, i) => buildPage(i, i === pages.length - 1)).join('\n\n');
|
||||
|
||||
const html = `<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<title>Исследуй Планету</title>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: { nunito: ['Nunito', 'sans-serif'] },
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@page { size: A4; margin: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-200 font-nunito">
|
||||
|
||||
${htmlPages}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
// ── Write output ────────────────────────────────────────────────────────────
|
||||
const outDir = path.join(ROOT, 'output/html');
|
||||
if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });
|
||||
|
||||
const outPath = path.join(outDir, 'space-worksheet3.html');
|
||||
fs.writeFileSync(outPath, html, 'utf-8');
|
||||
console.log(`Generated: ${outPath} (${pages.length} pages, ${pages.length * 20} problems)`);
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Generate output HTML from template + data for space-exploration documents.
|
||||
*
|
||||
* Usage: node generate.mjs <docId>
|
||||
* Example: node generate.mjs space-exploration-1
|
||||
*
|
||||
* Reads: docs/<docId>.template.html
|
||||
* Reads: docs/<docId>.data.json (optional — if missing, copies template as-is)
|
||||
* Writes: docs/<docId>.output.html
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
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 <docId>');
|
||||
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 data.json exists, apply it (space-exploration currently has no editor data)
|
||||
if (existsSync(dataPath)) {
|
||||
const data = JSON.parse(readFileSync(dataPath, 'utf-8'));
|
||||
console.log(`Data file found with ${data.pages?.length || 0} pages — no transforms defined yet for space-exploration`);
|
||||
}
|
||||
|
||||
writeFileSync(outputPath, html);
|
||||
console.log(`Generated: ${outputPath}`);
|
||||
@@ -0,0 +1,43 @@
|
||||
# Space Route Task Type
|
||||
|
||||
Navigate hex graph routes: player and enemy ships travel through a node graph. Child finds a path by following mathematical constraints between connected nodes.
|
||||
|
||||
## Generation
|
||||
|
||||
Generator script: `scripts/generate-route.mjs`
|
||||
|
||||
### Grid Rules
|
||||
- 7×9 hex grid with jitter, nodes evenly distributed across map area
|
||||
- Start nodes: Enemy = top-left corner, Player = bottom-left corner
|
||||
- Start nodes trimmed to exactly 2 edges
|
||||
|
||||
### Route Rules
|
||||
- No asteroids/decorations on route nodes or neighbors of start nodes
|
||||
- Routes use waypoints: route goes toward an offset waypoint for ~40% of steps, then changes direction toward final target (prevents straight-line paths)
|
||||
- Route length: 7-9 steps for enemy, player gets 10 empty cells
|
||||
- Ship orientation: check each ship image and set `flipEnemy`/`flipPlayer` flags so ships face right
|
||||
|
||||
### Difficulty
|
||||
- `diffRange: [minNodeValue, maxSpread]`
|
||||
- First number = minimum node value
|
||||
- Second = max |difference| between connected neighbors
|
||||
|
||||
## Scripts
|
||||
|
||||
- `scripts/generate-route.mjs` — full page generation (grid, edges, values, routes, HTML)
|
||||
- `scripts/apply-edits.mjs` — apply editor JSON back to HTML (regex-based style replacement)
|
||||
|
||||
## Editor
|
||||
|
||||
`editor.html?file={docId}` — two edit modes:
|
||||
|
||||
**Objects mode** (default): drag space icons, edges auto-follow
|
||||
**Nodes mode** (press M): Shift+click nodes, drag to reposition graph
|
||||
|
||||
Key controls:
|
||||
- `M`: toggle Objects/Nodes mode
|
||||
- `R`: toggle enemy route highlight
|
||||
- `H`: flip selected object horizontally
|
||||
- `+/-`: resize proportionally
|
||||
- `[/]`: rotate ±5°
|
||||
- Save: writes to `docs/{docId}.data.json`
|
||||
@@ -0,0 +1,111 @@
|
||||
{
|
||||
"file": "space-route-1.html",
|
||||
"pages": [
|
||||
{
|
||||
"page": 1,
|
||||
"objects": [
|
||||
{ "nodeId": 44, "type": "dest", "src": "asteroid5.png", "left": "157.0mm", "top": "183.5mm", "w": "30mm", "h": "30mm", "rotate": 5, "flipH": false },
|
||||
{ "nodeId": 4, "type": "deco", "src": "asteroid3.png", "left": "133.5mm", "top": "54.5mm", "w": "20mm", "h": "20mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 15, "type": "deco", "src": "asteroid7.png", "left": "81.0mm", "top": "97.0mm", "w": "54mm", "h": "52mm", "rotate": -20, "flipH": false },
|
||||
{ "nodeId": 17, "type": "deco", "src": "asteroid11.png", "left": "130.5mm", "top": "97.5mm", "w": "20mm", "h": "20mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 23, "type": "deco", "src": "pod1.png", "left": "115.5mm", "top": "122.0mm", "w": "34mm", "h": "22mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 29, "type": "deco", "src": "pod2.png", "left": "109.0mm", "top": "146.5mm", "w": "38mm", "h": "24mm", "rotate": 50, "flipH": false },
|
||||
{ "nodeId": 42, "type": "deco", "src": "freighter1.png", "left": "104.0mm", "top": "191.5mm", "w": "50mm", "h": "26mm", "rotate": -5, "flipH": false }
|
||||
],
|
||||
"nodes": [
|
||||
{ "nodeId": 0, "left": "53.0mm", "top": "48.0mm" }, { "nodeId": 1, "left": "54.0mm", "top": "69.5mm" }, { "nodeId": 2, "left": "84.0mm", "top": "59.0mm" }, { "nodeId": 3, "left": "108.5mm", "top": "56.5mm" }, { "nodeId": 4, "left": "137.5mm", "top": "59.5mm" }, { "nodeId": 5, "left": "160.0mm", "top": "59.5mm" }, { "nodeId": 6, "left": "190.0mm", "top": "78.0mm" }, { "nodeId": 7, "left": "26.0mm", "top": "72.5mm" }, { "nodeId": 8, "left": "53.5mm", "top": "91.0mm" }, { "nodeId": 9, "left": "96.5mm", "top": "73.5mm" }, { "nodeId": 10, "left": "115.7mm", "top": "74.1mm" }, { "nodeId": 11, "left": "144.4mm", "top": "81.4mm" }, { "nodeId": 12, "left": "167.5mm", "top": "83.5mm" }, { "nodeId": 13, "left": "16.0mm", "top": "107.0mm" }, { "nodeId": 14, "left": "47.5mm", "top": "112.0mm" }, { "nodeId": 15, "left": "80.0mm", "top": "96.5mm" }, { "nodeId": 16, "left": "108.5mm", "top": "97.7mm" }, { "nodeId": 17, "left": "131.2mm", "top": "103.4mm" }, { "nodeId": 18, "left": "155.9mm", "top": "95.4mm" }, { "nodeId": 19, "left": "189.0mm", "top": "114.5mm" }, { "nodeId": 20, "left": "29.0mm", "top": "125.0mm" }, { "nodeId": 21, "left": "70.0mm", "top": "118.5mm" }, { "nodeId": 22, "left": "91.6mm", "top": "117.7mm" }, { "nodeId": 23, "left": "113.5mm", "top": "119.8mm" }, { "nodeId": 24, "left": "142.3mm", "top": "117.4mm" }, { "nodeId": 25, "left": "174.0mm", "top": "125.0mm" }, { "nodeId": 26, "left": "23.5mm", "top": "142.1mm" }, { "nodeId": 27, "left": "50.0mm", "top": "145.1mm" }, { "nodeId": 28, "left": "78.0mm", "top": "149.0mm" }, { "nodeId": 29, "left": "103.2mm", "top": "146.3mm" }, { "nodeId": 30, "left": "135.0mm", "top": "139.5mm" }, { "nodeId": 31, "left": "158.9mm", "top": "143.9mm" }, { "nodeId": 32, "left": "177.7mm", "top": "148.2mm" }, { "nodeId": 33, "left": "36.9mm", "top": "166.8mm" }, { "nodeId": 34, "left": "62.6mm", "top": "162.8mm" }, { "nodeId": 35, "left": "100.5mm", "top": "169.0mm" }, { "nodeId": 36, "left": "129.5mm", "top": "170.5mm" }, { "nodeId": 37, "left": "146.0mm", "top": "155.0mm" }, { "nodeId": 38, "left": "166.1mm", "top": "160.7mm" }, { "nodeId": 39, "left": "23.8mm", "top": "191.2mm" }, { "nodeId": 40, "left": "55.3mm", "top": "183.2mm" }, { "nodeId": 41, "left": "78.0mm", "top": "176.0mm" }, { "nodeId": 42, "left": "102.0mm", "top": "199.5mm" }, { "nodeId": 43, "left": "139.5mm", "top": "195.0mm" }, { "nodeId": 44, "left": "157.5mm", "top": "176.0mm" }, { "nodeId": 45, "left": "180.8mm", "top": "190.7mm" }, { "nodeId": 46, "left": "36.3mm", "top": "208.1mm" }, { "nodeId": 47, "left": "57.5mm", "top": "209.0mm" }, { "nodeId": 48, "left": "79.5mm", "top": "215.0mm" }, { "nodeId": 49, "left": "121.0mm", "top": "209.0mm" }, { "nodeId": 50, "left": "146.0mm", "top": "211.5mm" }, { "nodeId": 51, "left": "169.5mm", "top": "206.0mm" }, { "nodeId": 52, "left": "24.3mm", "top": "235.9mm" }, { "nodeId": 53, "left": "57.2mm", "top": "230.9mm" }, { "nodeId": 54, "left": "82.5mm", "top": "232.7mm" }, { "nodeId": 55, "left": "102.5mm", "top": "227.0mm" }, { "nodeId": 56, "left": "125.6mm", "top": "227.0mm" }, { "nodeId": 57, "left": "157.3mm", "top": "233.1mm" }, { "nodeId": 58, "left": "181.5mm", "top": "226.4mm" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"page": 2,
|
||||
"objects": [
|
||||
{ "nodeId": 44, "type": "dest", "src": "pod6.png", "left": "174.5mm", "top": "179.5mm", "w": "20mm", "h": "19mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 5, "type": "deco", "src": "asteroid9.png", "left": "157.2mm", "top": "56.0mm", "w": "54mm", "h": "52mm", "rotate": 55, "flipH": false },
|
||||
{ "nodeId": 11, "type": "deco", "src": "asteroid14.png", "left": "146.9mm", "top": "82.1mm", "w": "16mm", "h": "15mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 21, "type": "deco", "src": "asteroid2.png", "left": "60.5mm", "top": "122.0mm", "w": "24mm", "h": "24mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 28, "type": "deco", "src": "pod4.png", "left": "85.0mm", "top": "142.5mm", "w": "24mm", "h": "15mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 34, "type": "deco", "src": "pod5.png", "left": "62.0mm", "top": "168.0mm", "w": "24mm", "h": "15mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 43, "type": "deco", "src": "freighter2.png", "left": "130.5mm", "top": "194.5mm", "w": "58mm", "h": "30mm", "rotate": -5, "flipH": false }
|
||||
],
|
||||
"nodes": [
|
||||
{ "nodeId": 0, "left": "44.5mm", "top": "47.5mm" }, { "nodeId": 1, "left": "62.0mm", "top": "58.5mm" }, { "nodeId": 2, "left": "93.0mm", "top": "69.5mm" }, { "nodeId": 3, "left": "101.0mm", "top": "54.5mm" }, { "nodeId": 4, "left": "127.1mm", "top": "52.9mm" }, { "nodeId": 5, "left": "152.5mm", "top": "58.0mm" }, { "nodeId": 6, "left": "185.0mm", "top": "54.5mm" }, { "nodeId": 7, "left": "19.5mm", "top": "76.5mm" }, { "nodeId": 8, "left": "63.0mm", "top": "78.5mm" }, { "nodeId": 9, "left": "104.0mm", "top": "86.5mm" }, { "nodeId": 10, "left": "120.9mm", "top": "75.2mm" }, { "nodeId": 11, "left": "146.9mm", "top": "82.1mm" }, { "nodeId": 12, "left": "166.6mm", "top": "75.0mm" }, { "nodeId": 13, "left": "12.0mm", "top": "106.0mm" }, { "nodeId": 14, "left": "31.0mm", "top": "100.5mm" }, { "nodeId": 15, "left": "62.5mm", "top": "98.5mm" }, { "nodeId": 16, "left": "106.8mm", "top": "103.6mm" }, { "nodeId": 17, "left": "128.7mm", "top": "102.1mm" }, { "nodeId": 18, "left": "155.9mm", "top": "99.8mm" }, { "nodeId": 19, "left": "180.8mm", "top": "96.9mm" }, { "nodeId": 20, "left": "22.0mm", "top": "124.5mm" }, { "nodeId": 21, "left": "59.0mm", "top": "120.0mm" }, { "nodeId": 22, "left": "89.5mm", "top": "119.0mm" }, { "nodeId": 23, "left": "121.5mm", "top": "119.5mm" }, { "nodeId": 24, "left": "141.9mm", "top": "124.3mm" }, { "nodeId": 25, "left": "168.5mm", "top": "118.0mm" }, { "nodeId": 26, "left": "14.0mm", "top": "155.0mm" }, { "nodeId": 27, "left": "50.8mm", "top": "142.4mm" }, { "nodeId": 28, "left": "85.5mm", "top": "141.0mm" }, { "nodeId": 29, "left": "110.3mm", "top": "147.9mm" }, { "nodeId": 30, "left": "128.0mm", "top": "153.5mm" }, { "nodeId": 31, "left": "162.3mm", "top": "144.4mm" }, { "nodeId": 32, "left": "188.0mm", "top": "129.0mm" }, { "nodeId": 33, "left": "36.2mm", "top": "163.9mm" }, { "nodeId": 34, "left": "66.0mm", "top": "167.5mm" }, { "nodeId": 35, "left": "90.1mm", "top": "164.2mm" }, { "nodeId": 36, "left": "113.3mm", "top": "169.1mm" }, { "nodeId": 37, "left": "140.5mm", "top": "170.5mm" }, { "nodeId": 38, "left": "187.5mm", "top": "153.5mm" }, { "nodeId": 39, "left": "15.0mm", "top": "184.0mm" }, { "nodeId": 40, "left": "51.0mm", "top": "188.5mm" }, { "nodeId": 41, "left": "69.5mm", "top": "185.5mm" }, { "nodeId": 42, "left": "93.0mm", "top": "189.5mm" }, { "nodeId": 43, "left": "137.5mm", "top": "196.0mm" }, { "nodeId": 44, "left": "172.0mm", "top": "177.5mm" }, { "nodeId": 45, "left": "197.0mm", "top": "173.5mm" }, { "nodeId": 46, "left": "26.0mm", "top": "202.5mm" }, { "nodeId": 47, "left": "66.0mm", "top": "202.0mm" }, { "nodeId": 48, "left": "81.5mm", "top": "207.5mm" }, { "nodeId": 49, "left": "107.5mm", "top": "211.0mm" }, { "nodeId": 50, "left": "160.0mm", "top": "213.5mm" }, { "nodeId": 51, "left": "181.5mm", "top": "222.5mm" }, { "nodeId": 52, "left": "36.5mm", "top": "236.0mm" }, { "nodeId": 53, "left": "49.0mm", "top": "214.0mm" }, { "nodeId": 54, "left": "76.5mm", "top": "223.5mm" }, { "nodeId": 55, "left": "100.5mm", "top": "232.0mm" }, { "nodeId": 56, "left": "134.0mm", "top": "222.5mm" }, { "nodeId": 57, "left": "156.2mm", "top": "233.5mm" }, { "nodeId": 58, "left": "200.5mm", "top": "214.0mm" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"page": 3,
|
||||
"objects": [
|
||||
{ "nodeId": 51, "type": "dest", "src": "freighter8.png", "left": "160.0mm", "top": "217.5mm", "w": "52mm", "h": "32mm", "rotate": -15, "flipH": false },
|
||||
{ "nodeId": 2, "type": "deco", "src": "asteroid1.png", "left": "67.5mm", "top": "67.5mm", "w": "20mm", "h": "20mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 9, "type": "deco", "src": "asteroid10.png", "left": "93.5mm", "top": "74.0mm", "w": "26mm", "h": "26mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 19, "type": "deco", "src": "asteroid6.png", "left": "187.6mm", "top": "100.3mm", "w": "16mm", "h": "15mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 23, "type": "deco", "src": "pod8.png", "left": "113.1mm", "top": "126.1mm", "w": "20mm", "h": "12mm", "rotate": -25, "flipH": false },
|
||||
{ "nodeId": 26, "type": "deco", "src": "pod10.png", "left": "19.5mm", "top": "143.0mm", "w": "36mm", "h": "23mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 35, "type": "deco", "src": "freighter5.png", "left": "86.5mm", "top": "168.5mm", "w": "58mm", "h": "30mm", "rotate": 0, "flipH": false }
|
||||
],
|
||||
"nodes": [
|
||||
{ "nodeId": 0, "left": "41.5mm", "top": "46.5mm" }, { "nodeId": 1, "left": "48.5mm", "top": "77.0mm" }, { "nodeId": 2, "left": "67.0mm", "top": "67.0mm" }, { "nodeId": 3, "left": "110.1mm", "top": "57.1mm" }, { "nodeId": 4, "left": "134.4mm", "top": "59.9mm" }, { "nodeId": 5, "left": "158.2mm", "top": "52.6mm" }, { "nodeId": 6, "left": "185.4mm", "top": "49.6mm" }, { "nodeId": 7, "left": "25.0mm", "top": "63.0mm" }, { "nodeId": 8, "left": "57.0mm", "top": "96.5mm" }, { "nodeId": 9, "left": "93.0mm", "top": "74.0mm" }, { "nodeId": 10, "left": "116.9mm", "top": "73.4mm" }, { "nodeId": 11, "left": "140.3mm", "top": "80.8mm" }, { "nodeId": 12, "left": "165.0mm", "top": "81.8mm" }, { "nodeId": 13, "left": "17.0mm", "top": "107.0mm" }, { "nodeId": 14, "left": "39.0mm", "top": "103.5mm" }, { "nodeId": 15, "left": "82.5mm", "top": "97.4mm" }, { "nodeId": 16, "left": "108.9mm", "top": "100.6mm" }, { "nodeId": 17, "left": "133.1mm", "top": "93.6mm" }, { "nodeId": 18, "left": "156.3mm", "top": "100.2mm" }, { "nodeId": 19, "left": "187.6mm", "top": "100.3mm" }, { "nodeId": 20, "left": "34.7mm", "top": "124.1mm" }, { "nodeId": 21, "left": "70.7mm", "top": "123.2mm" }, { "nodeId": 22, "left": "90.0mm", "top": "117.0mm" }, { "nodeId": 23, "left": "113.1mm", "top": "126.1mm" }, { "nodeId": 24, "left": "141.7mm", "top": "125.1mm" }, { "nodeId": 25, "left": "175.2mm", "top": "117.0mm" }, { "nodeId": 26, "left": "23.5mm", "top": "141.5mm" }, { "nodeId": 27, "left": "54.0mm", "top": "135.5mm" }, { "nodeId": 28, "left": "74.5mm", "top": "139.5mm" }, { "nodeId": 29, "left": "94.5mm", "top": "145.5mm" }, { "nodeId": 30, "left": "146.5mm", "top": "141.5mm" }, { "nodeId": 31, "left": "166.5mm", "top": "134.5mm" }, { "nodeId": 32, "left": "187.9mm", "top": "139.2mm" }, { "nodeId": 33, "left": "23.5mm", "top": "166.5mm" }, { "nodeId": 34, "left": "48.0mm", "top": "165.5mm" }, { "nodeId": 35, "left": "89.0mm", "top": "167.0mm" }, { "nodeId": 36, "left": "128.5mm", "top": "153.0mm" }, { "nodeId": 37, "left": "149.0mm", "top": "160.5mm" }, { "nodeId": 38, "left": "168.7mm", "top": "168.2mm" }, { "nodeId": 39, "left": "28.6mm", "top": "188.9mm" }, { "nodeId": 40, "left": "50.8mm", "top": "185.4mm" }, { "nodeId": 41, "left": "68.0mm", "top": "194.0mm" }, { "nodeId": 42, "left": "108.0mm", "top": "191.5mm" }, { "nodeId": 43, "left": "130.0mm", "top": "187.1mm" }, { "nodeId": 44, "left": "151.5mm", "top": "181.5mm" }, { "nodeId": 45, "left": "185.4mm", "top": "184.6mm" }, { "nodeId": 46, "left": "21.0mm", "top": "219.0mm" }, { "nodeId": 47, "left": "46.5mm", "top": "208.0mm" }, { "nodeId": 48, "left": "90.1mm", "top": "205.9mm" }, { "nodeId": 49, "left": "110.0mm", "top": "211.5mm" }, { "nodeId": 50, "left": "134.0mm", "top": "205.5mm" }, { "nodeId": 51, "left": "167.0mm", "top": "215.5mm" }, { "nodeId": 52, "left": "54.5mm", "top": "243.0mm" }, { "nodeId": 53, "left": "59.5mm", "top": "223.0mm" }, { "nodeId": 54, "left": "83.5mm", "top": "225.5mm" }, { "nodeId": 55, "left": "108.0mm", "top": "243.0mm" }, { "nodeId": 56, "left": "127.5mm", "top": "230.0mm" }, { "nodeId": 57, "left": "161.0mm", "top": "242.5mm" }, { "nodeId": 58, "left": "199.5mm", "top": "235.5mm" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"page": 4,
|
||||
"objects": [
|
||||
{ "nodeId": 44, "type": "dest", "src": "pod16.png", "left": "157.5mm", "top": "189.5mm", "w": "58mm", "h": "49mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 2, "type": "deco", "src": "asteroid12.png", "left": "73.5mm", "top": "69.5mm", "w": "20mm", "h": "20mm", "rotate": -60, "flipH": false },
|
||||
{ "nodeId": 10, "type": "deco", "src": "asteroid4.png", "left": "122.0mm", "top": "78.5mm", "w": "16mm", "h": "15mm", "rotate": -35, "flipH": false },
|
||||
{ "nodeId": 14, "type": "deco", "src": "asteroid15.png", "left": "38.0mm", "top": "103.5mm", "w": "20mm", "h": "20mm", "rotate": -35, "flipH": false },
|
||||
{ "nodeId": 27, "type": "deco", "src": "pod11.png", "left": "49.0mm", "top": "139.8mm", "w": "30mm", "h": "19mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 35, "type": "deco", "src": "pod13.png", "left": "91.1mm", "top": "166.1mm", "w": "32mm", "h": "20mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 40, "type": "deco", "src": "freighter3.png", "left": "52.5mm", "top": "190.0mm", "w": "58mm", "h": "34mm", "rotate": 0, "flipH": false }
|
||||
],
|
||||
"nodes": [
|
||||
{ "nodeId": 0, "left": "40.0mm", "top": "49.0mm" }, { "nodeId": 1, "left": "43.0mm", "top": "84.5mm" }, { "nodeId": 2, "left": "74.0mm", "top": "70.0mm" }, { "nodeId": 3, "left": "99.6mm", "top": "49.7mm" }, { "nodeId": 4, "left": "133.4mm", "top": "53.4mm" }, { "nodeId": 5, "left": "155.4mm", "top": "52.9mm" }, { "nodeId": 6, "left": "178.0mm", "top": "62.5mm" }, { "nodeId": 7, "left": "20.0mm", "top": "65.0mm" }, { "nodeId": 8, "left": "73.5mm", "top": "87.5mm" }, { "nodeId": 9, "left": "93.3mm", "top": "77.4mm" }, { "nodeId": 10, "left": "122.5mm", "top": "79.0mm" }, { "nodeId": 11, "left": "146.3mm", "top": "81.5mm" }, { "nodeId": 12, "left": "166.5mm", "top": "81.0mm" }, { "nodeId": 13, "left": "14.0mm", "top": "84.0mm" }, { "nodeId": 14, "left": "38.5mm", "top": "104.0mm" }, { "nodeId": 15, "left": "81.9mm", "top": "100.0mm" }, { "nodeId": 16, "left": "101.1mm", "top": "96.3mm" }, { "nodeId": 17, "left": "135.6mm", "top": "97.4mm" }, { "nodeId": 18, "left": "152.0mm", "top": "99.0mm" }, { "nodeId": 19, "left": "180.4mm", "top": "100.8mm" }, { "nodeId": 20, "left": "26.5mm", "top": "117.5mm" }, { "nodeId": 21, "left": "66.3mm", "top": "126.0mm" }, { "nodeId": 22, "left": "86.5mm", "top": "123.1mm" }, { "nodeId": 23, "left": "117.3mm", "top": "120.7mm" }, { "nodeId": 24, "left": "149.4mm", "top": "117.2mm" }, { "nodeId": 25, "left": "166.6mm", "top": "123.3mm" }, { "nodeId": 26, "left": "18.0mm", "top": "139.0mm" }, { "nodeId": 27, "left": "48.0mm", "top": "137.5mm" }, { "nodeId": 28, "left": "81.6mm", "top": "143.1mm" }, { "nodeId": 29, "left": "102.5mm", "top": "141.1mm" }, { "nodeId": 30, "left": "127.0mm", "top": "144.8mm" }, { "nodeId": 31, "left": "158.0mm", "top": "137.9mm" }, { "nodeId": 32, "left": "181.3mm", "top": "142.7mm" }, { "nodeId": 33, "left": "27.0mm", "top": "160.0mm" }, { "nodeId": 34, "left": "68.0mm", "top": "166.8mm" }, { "nodeId": 35, "left": "91.5mm", "top": "168.0mm" }, { "nodeId": 36, "left": "131.5mm", "top": "161.0mm" }, { "nodeId": 37, "left": "154.0mm", "top": "154.0mm" }, { "nodeId": 38, "left": "172.1mm", "top": "163.0mm" }, { "nodeId": 39, "left": "9.5mm", "top": "175.0mm" }, { "nodeId": 40, "left": "62.0mm", "top": "190.0mm" }, { "nodeId": 41, "left": "99.0mm", "top": "195.5mm" }, { "nodeId": 42, "left": "111.5mm", "top": "176.5mm" }, { "nodeId": 43, "left": "133.5mm", "top": "181.0mm" }, { "nodeId": 44, "left": "158.5mm", "top": "192.0mm" }, { "nodeId": 45, "left": "184.1mm", "top": "184.2mm" }, { "nodeId": 46, "left": "10.5mm", "top": "199.0mm" }, { "nodeId": 47, "left": "72.0mm", "top": "218.5mm" }, { "nodeId": 48, "left": "98.0mm", "top": "220.5mm" }, { "nodeId": 49, "left": "122.0mm", "top": "207.5mm" }, { "nodeId": 50, "left": "145.6mm", "top": "207.9mm" }, { "nodeId": 51, "left": "168.9mm", "top": "207.7mm" }, { "nodeId": 52, "left": "35.5mm", "top": "241.0mm" }, { "nodeId": 53, "left": "40.5mm", "top": "221.0mm" }, { "nodeId": 54, "left": "82.7mm", "top": "234.9mm" }, { "nodeId": 55, "left": "112.0mm", "top": "242.0mm" }, { "nodeId": 56, "left": "127.5mm", "top": "226.9mm" }, { "nodeId": 57, "left": "160.6mm", "top": "226.6mm" }, { "nodeId": 58, "left": "178.5mm", "top": "235.8mm" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"page": 5,
|
||||
"objects": [
|
||||
{ "nodeId": 44, "type": "dest", "src": "asteroid16.png", "left": "148.5mm", "top": "182.0mm", "w": "24mm", "h": "24mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 4, "type": "deco", "src": "asteroid8.png", "left": "132.5mm", "top": "55.5mm", "w": "28mm", "h": "28mm", "rotate": -10, "flipH": false },
|
||||
{ "nodeId": 9, "type": "deco", "src": "asteroid13.png", "left": "91.0mm", "top": "81.0mm", "w": "18mm", "h": "17mm", "rotate": -20, "flipH": false },
|
||||
{ "nodeId": 13, "type": "deco", "src": "asteroid3.png", "left": "16.5mm", "top": "104.0mm", "w": "20mm", "h": "20mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 24, "type": "deco", "src": "pod7.png", "left": "146.5mm", "top": "125.0mm", "w": "40mm", "h": "25mm", "rotate": 10, "flipH": false },
|
||||
{ "nodeId": 38, "type": "deco", "src": "pod9.png", "left": "179.5mm", "top": "159.5mm", "w": "26mm", "h": "17mm", "rotate": 15, "flipH": false },
|
||||
{ "nodeId": 50, "type": "deco", "src": "freighter6.png", "left": "147.0mm", "top": "221.5mm", "w": "60mm", "h": "31mm", "rotate": 0, "flipH": false }
|
||||
],
|
||||
"nodes": [
|
||||
{ "nodeId": 0, "left": "37.5mm", "top": "47.0mm" }, { "nodeId": 1, "left": "48.0mm", "top": "64.0mm" }, { "nodeId": 2, "left": "76.0mm", "top": "58.2mm" }, { "nodeId": 3, "left": "103.3mm", "top": "60.2mm" }, { "nodeId": 4, "left": "132.5mm", "top": "57.0mm" }, { "nodeId": 5, "left": "155.6mm", "top": "59.8mm" }, { "nodeId": 6, "left": "185.8mm", "top": "55.4mm" }, { "nodeId": 7, "left": "13.0mm", "top": "68.0mm" }, { "nodeId": 8, "left": "57.0mm", "top": "80.5mm" }, { "nodeId": 9, "left": "91.5mm", "top": "81.5mm" }, { "nodeId": 10, "left": "118.4mm", "top": "79.0mm" }, { "nodeId": 11, "left": "142.3mm", "top": "75.3mm" }, { "nodeId": 12, "left": "170.3mm", "top": "81.6mm" }, { "nodeId": 13, "left": "15.0mm", "top": "104.0mm" }, { "nodeId": 14, "left": "49.2mm", "top": "96.4mm" }, { "nodeId": 15, "left": "78.6mm", "top": "99.7mm" }, { "nodeId": 16, "left": "102.2mm", "top": "103.0mm" }, { "nodeId": 17, "left": "129.1mm", "top": "100.7mm" }, { "nodeId": 18, "left": "154.4mm", "top": "99.9mm" }, { "nodeId": 19, "left": "193.5mm", "top": "103.0mm" }, { "nodeId": 20, "left": "27.0mm", "top": "126.5mm" }, { "nodeId": 21, "left": "69.9mm", "top": "117.8mm" }, { "nodeId": 22, "left": "92.8mm", "top": "121.9mm" }, { "nodeId": 23, "left": "113.9mm", "top": "116.1mm" }, { "nodeId": 24, "left": "146.5mm", "top": "123.5mm" }, { "nodeId": 25, "left": "180.0mm", "top": "119.5mm" }, { "nodeId": 26, "left": "16.0mm", "top": "152.0mm" }, { "nodeId": 27, "left": "45.5mm", "top": "143.0mm" }, { "nodeId": 28, "left": "76.6mm", "top": "146.3mm" }, { "nodeId": 29, "left": "99.5mm", "top": "137.9mm" }, { "nodeId": 30, "left": "122.5mm", "top": "138.5mm" }, { "nodeId": 31, "left": "160.6mm", "top": "144.4mm" }, { "nodeId": 32, "left": "187.5mm", "top": "138.5mm" }, { "nodeId": 33, "left": "43.3mm", "top": "163.2mm" }, { "nodeId": 34, "left": "62.0mm", "top": "162.4mm" }, { "nodeId": 35, "left": "87.4mm", "top": "161.9mm" }, { "nodeId": 36, "left": "115.5mm", "top": "166.0mm" }, { "nodeId": 37, "left": "143.5mm", "top": "154.0mm" }, { "nodeId": 38, "left": "179.0mm", "top": "163.5mm" }, { "nodeId": 39, "left": "31.0mm", "top": "187.2mm" }, { "nodeId": 40, "left": "52.0mm", "top": "185.4mm" }, { "nodeId": 41, "left": "78.0mm", "top": "191.1mm" }, { "nodeId": 42, "left": "105.5mm", "top": "189.6mm" }, { "nodeId": 43, "left": "126.9mm", "top": "188.7mm" }, { "nodeId": 44, "left": "150.5mm", "top": "183.5mm" }, { "nodeId": 45, "left": "194.5mm", "top": "184.0mm" }, { "nodeId": 46, "left": "14.5mm", "top": "216.5mm" }, { "nodeId": 47, "left": "46.5mm", "top": "205.5mm" }, { "nodeId": 48, "left": "73.0mm", "top": "212.0mm" }, { "nodeId": 49, "left": "104.0mm", "top": "208.5mm" }, { "nodeId": 50, "left": "163.5mm", "top": "221.5mm" }, { "nodeId": 51, "left": "196.0mm", "top": "217.5mm" }, { "nodeId": 52, "left": "45.0mm", "top": "244.5mm" }, { "nodeId": 53, "left": "40.5mm", "top": "224.0mm" }, { "nodeId": 54, "left": "75.1mm", "top": "231.5mm" }, { "nodeId": 55, "left": "102.0mm", "top": "232.0mm" }, { "nodeId": 56, "left": "130.5mm", "top": "245.0mm" }, { "nodeId": 57, "left": "169.0mm", "top": "252.5mm" }, { "nodeId": 58, "left": "200.0mm", "top": "251.5mm" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"page": 6,
|
||||
"objects": [
|
||||
{ "nodeId": 51, "type": "dest", "src": "freighter2.png", "left": "174.5mm", "top": "211.0mm", "w": "60mm", "h": "40mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 4, "type": "deco", "src": "freighter9.png", "left": "133.5mm", "top": "48.5mm", "w": "52mm", "h": "27mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 10, "type": "deco", "src": "freighter10.png", "left": "104.0mm", "top": "84.5mm", "w": "54mm", "h": "28mm", "rotate": -5, "flipH": false },
|
||||
{ "nodeId": 13, "type": "deco", "src": "pod14.png", "left": "20.5mm", "top": "106.5mm", "w": "48mm", "h": "30mm", "rotate": -20, "flipH": false },
|
||||
{ "nodeId": 24, "type": "deco", "src": "pod15.png", "left": "140.0mm", "top": "114.5mm", "w": "28mm", "h": "18mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 32, "type": "deco", "src": "pod17.png", "left": "182.5mm", "top": "142.0mm", "w": "38mm", "h": "24mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 35, "type": "deco", "src": "asteroid3.png", "left": "77.5mm", "top": "161.0mm", "w": "20mm", "h": "20mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 42, "type": "deco", "src": "asteroid11.png", "left": "101.0mm", "top": "191.5mm", "w": "20mm", "h": "20mm", "rotate": 0, "flipH": false }
|
||||
],
|
||||
"nodes": [
|
||||
{ "nodeId": 0, "left": "35.5mm", "top": "49.5mm" }, { "nodeId": 1, "left": "53.5mm", "top": "68.0mm" }, { "nodeId": 2, "left": "82.1mm", "top": "54.4mm" }, { "nodeId": 3, "left": "102.5mm", "top": "59.5mm" }, { "nodeId": 4, "left": "132.0mm", "top": "53.5mm" }, { "nodeId": 5, "left": "164.5mm", "top": "49.0mm" }, { "nodeId": 6, "left": "189.5mm", "top": "52.0mm" }, { "nodeId": 7, "left": "18.5mm", "top": "80.0mm" }, { "nodeId": 8, "left": "60.9mm", "top": "80.5mm" }, { "nodeId": 9, "left": "84.5mm", "top": "70.5mm" }, { "nodeId": 10, "left": "101.5mm", "top": "85.5mm" }, { "nodeId": 11, "left": "155.0mm", "top": "75.5mm" }, { "nodeId": 12, "left": "189.5mm", "top": "80.0mm" }, { "nodeId": 13, "left": "26.5mm", "top": "103.5mm" }, { "nodeId": 14, "left": "56.0mm", "top": "99.8mm" }, { "nodeId": 15, "left": "78.0mm", "top": "104.0mm" }, { "nodeId": 16, "left": "107.7mm", "top": "103.0mm" }, { "nodeId": 17, "left": "133.0mm", "top": "93.8mm" }, { "nodeId": 18, "left": "158.8mm", "top": "97.4mm" }, { "nodeId": 19, "left": "188.1mm", "top": "104.0mm" }, { "nodeId": 20, "left": "40.0mm", "top": "123.0mm" }, { "nodeId": 21, "left": "62.0mm", "top": "131.5mm" }, { "nodeId": 22, "left": "92.1mm", "top": "121.0mm" }, { "nodeId": 23, "left": "113.5mm", "top": "123.5mm" }, { "nodeId": 24, "left": "141.0mm", "top": "114.5mm" }, { "nodeId": 25, "left": "174.8mm", "top": "122.5mm" }, { "nodeId": 26, "left": "20.0mm", "top": "140.5mm" }, { "nodeId": 27, "left": "49.1mm", "top": "138.9mm" }, { "nodeId": 28, "left": "74.5mm", "top": "144.0mm" }, { "nodeId": 29, "left": "107.5mm", "top": "142.0mm" }, { "nodeId": 30, "left": "127.9mm", "top": "142.6mm" }, { "nodeId": 31, "left": "146.5mm", "top": "146.5mm" }, { "nodeId": 32, "left": "177.0mm", "top": "140.0mm" }, { "nodeId": 33, "left": "23.0mm", "top": "162.5mm" }, { "nodeId": 34, "left": "53.5mm", "top": "157.5mm" }, { "nodeId": 35, "left": "77.5mm", "top": "160.0mm" }, { "nodeId": 36, "left": "119.0mm", "top": "160.5mm" }, { "nodeId": 37, "left": "141.5mm", "top": "173.5mm" }, { "nodeId": 38, "left": "174.0mm", "top": "168.5mm" }, { "nodeId": 39, "left": "30.0mm", "top": "186.9mm" }, { "nodeId": 40, "left": "53.7mm", "top": "181.6mm" }, { "nodeId": 41, "left": "73.6mm", "top": "190.8mm" }, { "nodeId": 42, "left": "101.0mm", "top": "192.5mm" }, { "nodeId": 43, "left": "121.0mm", "top": "186.0mm" }, { "nodeId": 44, "left": "153.7mm", "top": "187.6mm" }, { "nodeId": 45, "left": "182.3mm", "top": "189.9mm" }, { "nodeId": 46, "left": "13.5mm", "top": "210.5mm" }, { "nodeId": 47, "left": "42.5mm", "top": "207.0mm" }, { "nodeId": 48, "left": "79.5mm", "top": "209.5mm" }, { "nodeId": 49, "left": "115.9mm", "top": "208.0mm" }, { "nodeId": 50, "left": "132.5mm", "top": "212.5mm" }, { "nodeId": 51, "left": "176.5mm", "top": "212.5mm" }, { "nodeId": 52, "left": "44.5mm", "top": "243.5mm" }, { "nodeId": 53, "left": "46.0mm", "top": "224.0mm" }, { "nodeId": 54, "left": "81.5mm", "top": "225.9mm" }, { "nodeId": 55, "left": "96.5mm", "top": "242.5mm" }, { "nodeId": 56, "left": "124.5mm", "top": "243.0mm" }, { "nodeId": 57, "left": "147.5mm", "top": "230.0mm" }, { "nodeId": 58, "left": "180.0mm", "top": "240.0mm" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"page": 7,
|
||||
"objects": [
|
||||
{ "nodeId": 43, "type": "dest", "src": "pod18.png", "left": "121.0mm", "top": "202.5mm", "w": "32mm", "h": "28mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 4, "type": "deco", "src": "asteroid7.png", "left": "132.0mm", "top": "42.5mm", "w": "46mm", "h": "44mm", "rotate": -10, "flipH": false },
|
||||
{ "nodeId": 12, "type": "deco", "src": "asteroid15.png", "left": "175.5mm", "top": "71.0mm", "w": "20mm", "h": "20mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 23, "type": "deco", "src": "asteroid5.png", "left": "111.0mm", "top": "113.0mm", "w": "22mm", "h": "22mm", "rotate": -10, "flipH": false },
|
||||
{ "nodeId": 31, "type": "deco", "src": "pod3.png", "left": "157.0mm", "top": "142.5mm", "w": "40mm", "h": "25mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 29, "type": "deco", "src": "pod12.png", "left": "96.5mm", "top": "139.0mm", "w": "28mm", "h": "18mm", "rotate": 0, "flipH": false },
|
||||
{ "nodeId": 44, "type": "deco", "src": "freighter4.png", "left": "159.5mm", "top": "189.5mm", "w": "58mm", "h": "30mm", "rotate": 0, "flipH": false }
|
||||
],
|
||||
"nodes": [
|
||||
{ "nodeId": 0, "left": "39.0mm", "top": "48.0mm" }, { "nodeId": 1, "left": "48.5mm", "top": "65.5mm" }, { "nodeId": 2, "left": "83.4mm", "top": "54.6mm" }, { "nodeId": 3, "left": "100.0mm", "top": "53.3mm" }, { "nodeId": 4, "left": "132.5mm", "top": "42.0mm" }, { "nodeId": 5, "left": "165.5mm", "top": "44.5mm" }, { "nodeId": 6, "left": "194.5mm", "top": "59.5mm" }, { "nodeId": 7, "left": "15.0mm", "top": "62.5mm" }, { "nodeId": 8, "left": "52.5mm", "top": "83.5mm" }, { "nodeId": 9, "left": "90.9mm", "top": "75.7mm" }, { "nodeId": 10, "left": "122.8mm", "top": "80.9mm" }, { "nodeId": 11, "left": "144.8mm", "top": "72.0mm" }, { "nodeId": 12, "left": "175.5mm", "top": "71.0mm" }, { "nodeId": 13, "left": "16.5mm", "top": "96.5mm" }, { "nodeId": 14, "left": "41.5mm", "top": "95.0mm" }, { "nodeId": 15, "left": "78.3mm", "top": "97.0mm" }, { "nodeId": 16, "left": "99.5mm", "top": "97.5mm" }, { "nodeId": 17, "left": "132.2mm", "top": "100.3mm" }, { "nodeId": 18, "left": "155.8mm", "top": "96.1mm" }, { "nodeId": 19, "left": "195.0mm", "top": "93.0mm" }, { "nodeId": 20, "left": "30.5mm", "top": "118.0mm" }, { "nodeId": 21, "left": "65.5mm", "top": "118.4mm" }, { "nodeId": 22, "left": "85.5mm", "top": "123.0mm" }, { "nodeId": 23, "left": "111.0mm", "top": "113.0mm" }, { "nodeId": 24, "left": "141.0mm", "top": "123.5mm" }, { "nodeId": 25, "left": "168.0mm", "top": "116.0mm" }, { "nodeId": 26, "left": "18.0mm", "top": "148.0mm" }, { "nodeId": 27, "left": "53.5mm", "top": "140.0mm" }, { "nodeId": 28, "left": "81.7mm", "top": "142.4mm" }, { "nodeId": 29, "left": "97.5mm", "top": "138.5mm" }, { "nodeId": 30, "left": "129.5mm", "top": "145.0mm" }, { "nodeId": 31, "left": "157.0mm", "top": "142.5mm" }, { "nodeId": 32, "left": "189.8mm", "top": "136.1mm" }, { "nodeId": 33, "left": "30.0mm", "top": "168.5mm" }, { "nodeId": 34, "left": "54.5mm", "top": "162.0mm" }, { "nodeId": 35, "left": "89.4mm", "top": "160.7mm" }, { "nodeId": 36, "left": "117.5mm", "top": "166.5mm" }, { "nodeId": 37, "left": "139.0mm", "top": "172.5mm" }, { "nodeId": 38, "left": "173.0mm", "top": "158.5mm" }, { "nodeId": 39, "left": "22.0mm", "top": "192.0mm" }, { "nodeId": 40, "left": "52.8mm", "top": "190.0mm" }, { "nodeId": 41, "left": "73.0mm", "top": "186.0mm" }, { "nodeId": 42, "left": "98.0mm", "top": "199.5mm" }, { "nodeId": 43, "left": "123.0mm", "top": "197.5mm" }, { "nodeId": 44, "left": "160.0mm", "top": "190.0mm" }, { "nodeId": 45, "left": "186.3mm", "top": "184.2mm" }, { "nodeId": 46, "left": "43.0mm", "top": "214.5mm" }, { "nodeId": 47, "left": "70.0mm", "top": "207.0mm" }, { "nodeId": 48, "left": "82.5mm", "top": "221.5mm" }, { "nodeId": 49, "left": "109.0mm", "top": "219.5mm" }, { "nodeId": 50, "left": "140.0mm", "top": "212.5mm" }, { "nodeId": 51, "left": "167.0mm", "top": "215.5mm" }, { "nodeId": 52, "left": "21.5mm", "top": "237.0mm" }, { "nodeId": 53, "left": "52.5mm", "top": "230.5mm" }, { "nodeId": 54, "left": "78.5mm", "top": "238.5mm" }, { "nodeId": 55, "left": "102.0mm", "top": "242.0mm" }, { "nodeId": 56, "left": "129.5mm", "top": "238.5mm" }, { "nodeId": 57, "left": "160.0mm", "top": "240.0mm" }, { "nodeId": 58, "left": "190.0mm", "top": "241.0mm" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
# Space Route 1
|
||||
|
||||
**Title:** Проложи Маршрут
|
||||
|
||||
## Notes
|
||||
|
||||
9-page space route worksheet. Player and enemy navigate a hex graph.
|
||||
Generated by `scripts/generate-route.mjs` with per-page seed configs.
|
||||
|
||||
See `scripts/generate-route.mjs` PAGES array for full page configs including:
|
||||
- diffRange (difficulty), routeLength, seeds
|
||||
- Ship/enemy images, destination objects, decorative objects
|
||||
- flipEnemy/flipPlayer flags for ship orientation
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,687 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<title>Проложи Маршрут</title>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: { nunito: ['Nunito', 'sans-serif'] },
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@page { size: A4; margin: 0; }
|
||||
body { font-family: 'Nunito', sans-serif; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-200 font-nunito">
|
||||
|
||||
<script>
|
||||
// ============================================================
|
||||
// CONFIGURATION PER PAGE
|
||||
// ============================================================
|
||||
// diffRange: [minNodeValue, maxSpread]
|
||||
const PAGES = [
|
||||
{
|
||||
enemyShipImg: '../../assets/hero-images/spaceship4.jpeg',
|
||||
enemyLabel: 'Пиратский крейсер',
|
||||
playerShipImg: '../../assets/hero-images/spaceship2.png',
|
||||
footerImg: '../../assets/footers/planet3.jpeg',
|
||||
destObjectImg: '../../assets/icons/pack3-asteroids/asteroid5.png',
|
||||
decoObjects: [
|
||||
{ img: '../../assets/icons/pack3-asteroids/asteroid3.png' },
|
||||
{ img: '../../assets/icons/pack3-asteroids/asteroid7.png' },
|
||||
{ img: '../../assets/icons/pack3-asteroids/asteroid11.png' },
|
||||
],
|
||||
diffRange: [3, 6],
|
||||
routeLength: 5,
|
||||
seed: 42001,
|
||||
flipEnemy: false, // spaceship4 faces right
|
||||
flipPlayer: true, // spaceship2 faces left
|
||||
},
|
||||
{
|
||||
enemyShipImg: '../../assets/hero-images/spaceship6.jpeg',
|
||||
enemyLabel: 'Патрульный разведчик',
|
||||
playerShipImg: '../../assets/hero-images/spaceship7.png',
|
||||
footerImg: '../../assets/footers/planet5.jpeg',
|
||||
destObjectImg: '../../assets/icons/pack3-asteroids/asteroid9.png',
|
||||
decoObjects: [
|
||||
{ img: '../../assets/icons/pack3-asteroids/asteroid14.png' },
|
||||
{ img: '../../assets/icons/pack3-asteroids/asteroid2.png' },
|
||||
{ img: '../../assets/icons/pack3-asteroids/asteroid16.png' },
|
||||
{ img: '../../assets/icons/pack3-asteroids/asteroid4.png' },
|
||||
],
|
||||
diffRange: [4, 10],
|
||||
routeLength: 5,
|
||||
seed: 42002,
|
||||
flipEnemy: true, // spaceship6 faces left
|
||||
flipPlayer: true, // spaceship7 faces left
|
||||
},
|
||||
{
|
||||
enemyShipImg: '../../assets/hero-images/spaceship3.jpeg',
|
||||
enemyLabel: 'Контрабандист',
|
||||
playerShipImg: '../../assets/hero-images/spaceship9.png',
|
||||
footerImg: '../../assets/footers/planet1.jpeg',
|
||||
destObjectImg: '../../assets/icons/pack3-asteroids/asteroid1.png',
|
||||
decoObjects: [
|
||||
{ img: '../../assets/icons/pack3-asteroids/asteroid10.png' },
|
||||
{ img: '../../assets/icons/pack3-asteroids/asteroid6.png' },
|
||||
{ img: '../../assets/icons/pack3-asteroids/asteroid12.png' },
|
||||
],
|
||||
diffRange: [2, 18],
|
||||
routeLength: 6,
|
||||
seed: 42003,
|
||||
flipEnemy: false, // spaceship3 faces right
|
||||
flipPlayer: true, // spaceship9 faces left
|
||||
},
|
||||
];
|
||||
|
||||
const PLAYER_ROUTE_CELLS = 10;
|
||||
const GRID_COLS = 6;
|
||||
const GRID_ROWS = 7;
|
||||
|
||||
// ============================================================
|
||||
// SEEDED PRNG (mulberry32) — stable output across reloads
|
||||
// ============================================================
|
||||
let _seed = 0;
|
||||
function seedRng(s) { _seed = s | 0; }
|
||||
function seededRandom() {
|
||||
_seed |= 0; _seed = _seed + 0x6D2B79F5 | 0;
|
||||
let t = Math.imul(_seed ^ _seed >>> 15, 1 | _seed);
|
||||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// GRAPH ALGORITHM
|
||||
// ============================================================
|
||||
const NODE_R_MM = 5;
|
||||
const MAP_TOP = 44;
|
||||
const MAP_BOTTOM = 242;
|
||||
const MAP_LEFT = 14;
|
||||
const MAP_RIGHT = 196;
|
||||
|
||||
function rand(min, max) {
|
||||
return Math.floor(seededRandom() * (max - min + 1)) + min;
|
||||
}
|
||||
function randF(min, max) {
|
||||
return min + seededRandom() * (max - min);
|
||||
}
|
||||
function distN(a, b) {
|
||||
return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2);
|
||||
}
|
||||
|
||||
function generateNodes() {
|
||||
const nodes = [];
|
||||
const cellW = (MAP_RIGHT - MAP_LEFT) / GRID_COLS;
|
||||
const cellH = (MAP_BOTTOM - MAP_TOP) / GRID_ROWS;
|
||||
const jitter = Math.min(cellW, cellH) * 0.25;
|
||||
|
||||
let id = 0;
|
||||
for (let row = 0; row < GRID_ROWS; row++) {
|
||||
for (let col = 0; col < GRID_COLS; col++) {
|
||||
const hexOffset = (row % 2 === 1) ? cellW * 0.5 : 0;
|
||||
const baseX = MAP_LEFT + col * cellW + cellW / 2 + hexOffset;
|
||||
const baseY = MAP_TOP + row * cellH + cellH / 2;
|
||||
|
||||
if (baseX < MAP_LEFT + 5 || baseX > MAP_RIGHT - 5) continue;
|
||||
|
||||
const x = baseX + randF(-jitter, jitter);
|
||||
const y = baseY + randF(-jitter, jitter);
|
||||
|
||||
const cx = Math.max(MAP_LEFT + NODE_R_MM, Math.min(MAP_RIGHT - NODE_R_MM, x));
|
||||
const cy = Math.max(MAP_TOP + NODE_R_MM, Math.min(MAP_BOTTOM - NODE_R_MM, y));
|
||||
|
||||
nodes.push({ x: cx, y: cy, id: id++, value: 0, neighbors: [] });
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
function generateEdges(nodes) {
|
||||
const edges = [];
|
||||
const maxEdgeDist = 45;
|
||||
|
||||
const candidates = [];
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
for (let j = i + 1; j < nodes.length; j++) {
|
||||
const d = distN(nodes[i], nodes[j]);
|
||||
if (d <= maxEdgeDist) candidates.push({ i, j, d });
|
||||
}
|
||||
}
|
||||
candidates.sort((a, b) => a.d - b.d);
|
||||
|
||||
const MAX_DEGREE = 5;
|
||||
for (const { i, j } of candidates) {
|
||||
if (nodes[i].neighbors.length >= MAX_DEGREE || nodes[j].neighbors.length >= MAX_DEGREE) continue;
|
||||
let crosses = false;
|
||||
for (const e of edges) {
|
||||
if (e.i === i || e.j === i || e.i === j || e.j === j) continue;
|
||||
if (segmentsIntersect(nodes[i], nodes[j], nodes[e.i], nodes[e.j])) { crosses = true; break; }
|
||||
}
|
||||
if (!crosses) {
|
||||
edges.push({ i, j });
|
||||
nodes[i].neighbors.push(j);
|
||||
nodes[j].neighbors.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
ensureConnected(nodes, edges);
|
||||
|
||||
// Ensure min degree 2
|
||||
for (const n of nodes) {
|
||||
if (n.neighbors.length < 2) {
|
||||
let best = null, bestDist = Infinity;
|
||||
for (const other of nodes) {
|
||||
if (other.id === n.id || n.neighbors.includes(other.id)) continue;
|
||||
const d = distN(n, other);
|
||||
if (d < bestDist) { bestDist = d; best = other; }
|
||||
}
|
||||
if (best) {
|
||||
edges.push({ i: n.id, j: best.id });
|
||||
n.neighbors.push(best.id);
|
||||
best.neighbors.push(n.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return edges;
|
||||
}
|
||||
|
||||
// Trim a node's edges down to exactly targetDegree, keeping nearest neighbors
|
||||
function trimNodeDegree(nodes, edges, nodeId, targetDegree) {
|
||||
const n = nodes[nodeId];
|
||||
while (n.neighbors.length > targetDegree) {
|
||||
// Remove the farthest neighbor
|
||||
let farthestNb = -1, farthestDist = 0;
|
||||
for (const nb of n.neighbors) {
|
||||
const d = distN(n, nodes[nb]);
|
||||
if (d > farthestDist) { farthestDist = d; farthestNb = nb; }
|
||||
}
|
||||
// Remove edge
|
||||
n.neighbors = n.neighbors.filter(nb => nb !== farthestNb);
|
||||
nodes[farthestNb].neighbors = nodes[farthestNb].neighbors.filter(nb => nb !== nodeId);
|
||||
// Remove from edges array
|
||||
for (let ei = edges.length - 1; ei >= 0; ei--) {
|
||||
const e = edges[ei];
|
||||
if ((e.i === nodeId && e.j === farthestNb) || (e.j === nodeId && e.i === farthestNb)) {
|
||||
edges.splice(ei, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ensureConnected(nodes, edges) {
|
||||
const component = new Array(nodes.length).fill(-1);
|
||||
let compId = 0;
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
if (component[i] !== -1) continue;
|
||||
const queue = [i];
|
||||
component[i] = compId;
|
||||
while (queue.length) {
|
||||
const cur = queue.shift();
|
||||
for (const nb of nodes[cur].neighbors) {
|
||||
if (component[nb] === -1) { component[nb] = compId; queue.push(nb); }
|
||||
}
|
||||
}
|
||||
compId++;
|
||||
}
|
||||
for (let c = 1; c < compId; c++) {
|
||||
let best = null, bestDist = Infinity;
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
if (component[i] !== 0) continue;
|
||||
for (let j = 0; j < nodes.length; j++) {
|
||||
if (component[j] !== c) continue;
|
||||
const d = distN(nodes[i], nodes[j]);
|
||||
if (d < bestDist) { bestDist = d; best = { i, j }; }
|
||||
}
|
||||
}
|
||||
if (best) {
|
||||
edges.push(best);
|
||||
nodes[best.i].neighbors.push(best.j);
|
||||
nodes[best.j].neighbors.push(best.i);
|
||||
for (let k = 0; k < nodes.length; k++) {
|
||||
if (component[k] === c) component[k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function segmentsIntersect(p1, p2, p3, p4) {
|
||||
const d1 = crossP(p3, p4, p1), d2 = crossP(p3, p4, p2);
|
||||
const d3 = crossP(p1, p2, p3), d4 = crossP(p1, p2, p4);
|
||||
return ((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) &&
|
||||
((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0));
|
||||
}
|
||||
function crossP(pi, pj, pk) {
|
||||
return (pk.x - pi.x) * (pj.y - pi.y) - (pj.x - pi.x) * (pk.y - pi.y);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// VALUE ASSIGNMENT
|
||||
// ============================================================
|
||||
|
||||
function assignValues(nodes, minVal, maxSpread) {
|
||||
const maxVal = minVal + Math.ceil(maxSpread * 1.3);
|
||||
const order = [...Array(nodes.length).keys()];
|
||||
order.sort((a, b) => nodes[b].neighbors.length - nodes[a].neighbors.length);
|
||||
|
||||
for (let attempt = 0; attempt < 300; attempt++) {
|
||||
if (tryAssign(nodes, order, minVal, maxSpread, maxVal)) {
|
||||
if (validateGraph(nodes, minVal, maxSpread)) return true;
|
||||
}
|
||||
for (let i = order.length - 1; i > 0; i--) {
|
||||
if (Math.random() < 0.4) {
|
||||
const j = rand(0, i);
|
||||
[order[i], order[j]] = [order[j], order[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function tryAssign(nodes, order, minVal, maxSpread, maxVal) {
|
||||
for (const n of nodes) n.value = -1;
|
||||
|
||||
for (const idx of order) {
|
||||
const candidates = [];
|
||||
for (let v = minVal; v <= maxVal; v++) {
|
||||
let valid = true;
|
||||
const signedDiffs = [];
|
||||
|
||||
for (const nb of nodes[idx].neighbors) {
|
||||
if (nodes[nb].value === -1) continue;
|
||||
const absDiff = Math.abs(v - nodes[nb].value);
|
||||
if (absDiff < 1 || absDiff > maxSpread) { valid = false; break; }
|
||||
const sd = v - nodes[nb].value;
|
||||
if (signedDiffs.includes(sd)) { valid = false; break; }
|
||||
signedDiffs.push(sd);
|
||||
}
|
||||
if (!valid) continue;
|
||||
|
||||
for (const nb of nodes[idx].neighbors) {
|
||||
if (nodes[nb].value === -1) continue;
|
||||
const myDiff = v - nodes[nb].value;
|
||||
for (const nb2 of nodes[nb].neighbors) {
|
||||
if (nb2 === idx || nodes[nb2].value === -1) continue;
|
||||
if (nodes[nb2].value - nodes[nb].value === myDiff) { valid = false; break; }
|
||||
}
|
||||
if (!valid) break;
|
||||
}
|
||||
if (valid) candidates.push(v);
|
||||
}
|
||||
if (candidates.length === 0) return false;
|
||||
const center = minVal + maxSpread * 0.5;
|
||||
candidates.sort((a, b) => Math.abs(a - center) - Math.abs(b - center));
|
||||
const pick = Math.min(candidates.length - 1, Math.floor(Math.random() * Math.min(candidates.length, 4)));
|
||||
nodes[idx].value = candidates[pick];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function validateGraph(nodes, minVal, maxSpread) {
|
||||
for (const n of nodes) {
|
||||
if (n.value < minVal) return false;
|
||||
const diffs = [];
|
||||
for (const nb of n.neighbors) {
|
||||
const d = nodes[nb].value - n.value;
|
||||
const ad = Math.abs(d);
|
||||
if (ad < 1 || ad > maxSpread) return false;
|
||||
if (diffs.includes(d)) return false;
|
||||
diffs.push(d);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// ROUTE FINDING — directional, avoids loops
|
||||
// ============================================================
|
||||
|
||||
// Find corner node: top-left or bottom-left
|
||||
function findCornerNode(nodes, corner) {
|
||||
let sorted;
|
||||
if (corner === 'top-left') {
|
||||
sorted = [...nodes].sort((a, b) => (a.x + a.y * 2) - (b.x + b.y * 2));
|
||||
} else {
|
||||
// bottom-left: low x, high y
|
||||
sorted = [...nodes].sort((a, b) => (a.x - a.y * 2) - (b.x - b.y * 2));
|
||||
}
|
||||
return sorted[0];
|
||||
}
|
||||
|
||||
// Directional route: prefer moving toward a target area, avoid backtracking
|
||||
function findDirectionalRoute(nodes, startId, length, targetArea) {
|
||||
// targetArea: {x, y} — general direction to aim for
|
||||
const best = { path: null, score: -Infinity };
|
||||
|
||||
for (let trial = 0; trial < 30; trial++) {
|
||||
const path = [startId];
|
||||
if (buildDirectionalPath(nodes, path, length, targetArea)) {
|
||||
const score = routeQualityScore(nodes, path, targetArea);
|
||||
if (score > best.score) {
|
||||
best.path = [...path];
|
||||
best.score = score;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best.path;
|
||||
}
|
||||
|
||||
function buildDirectionalPath(nodes, path, targetLen, target) {
|
||||
if (path.length === targetLen + 1) return true;
|
||||
const current = nodes[path[path.length - 1]];
|
||||
const nbs = [...current.neighbors].filter(nb => !path.includes(nb));
|
||||
if (nbs.length === 0) return false;
|
||||
|
||||
// Score each neighbor: prefer those closer to target, penalize going backward
|
||||
const scored = nbs.map(nb => {
|
||||
const n = nodes[nb];
|
||||
const distToTarget = Math.sqrt((n.x - target.x) ** 2 + (n.y - target.y) ** 2);
|
||||
// Progress: how much closer we get vs current position
|
||||
const curDist = Math.sqrt((current.x - target.x) ** 2 + (current.y - target.y) ** 2);
|
||||
const progress = curDist - distToTarget;
|
||||
// Small random factor for variety
|
||||
return { nb, score: progress + randF(-15, 15) };
|
||||
});
|
||||
scored.sort((a, b) => b.score - a.score);
|
||||
|
||||
for (const { nb } of scored) {
|
||||
path.push(nb);
|
||||
if (buildDirectionalPath(nodes, path, targetLen, target)) return true;
|
||||
path.pop();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Score route: higher = more directional, less loopy
|
||||
function routeQualityScore(nodes, path, target) {
|
||||
const start = nodes[path[0]];
|
||||
const end = nodes[path[path.length - 1]];
|
||||
|
||||
// Distance from end to target
|
||||
const endDist = Math.sqrt((end.x - target.x) ** 2 + (end.y - target.y) ** 2);
|
||||
|
||||
// Straightness: total path length vs straight-line distance
|
||||
let totalDist = 0;
|
||||
for (let i = 1; i < path.length; i++) {
|
||||
totalDist += distN(nodes[path[i - 1]], nodes[path[i]]);
|
||||
}
|
||||
const straightLine = distN(start, end);
|
||||
const straightness = straightLine / (totalDist + 1);
|
||||
|
||||
return -endDist * 0.5 + straightness * 50 + straightLine * 0.3;
|
||||
}
|
||||
|
||||
function findShortestPath(nodes, fromId, toId) {
|
||||
const prev = new Array(nodes.length).fill(-1);
|
||||
const visited = new Set([fromId]);
|
||||
const queue = [fromId];
|
||||
while (queue.length) {
|
||||
const cur = queue.shift();
|
||||
if (cur === toId) break;
|
||||
for (const nb of nodes[cur].neighbors) {
|
||||
if (!visited.has(nb)) { visited.add(nb); prev[nb] = cur; queue.push(nb); }
|
||||
}
|
||||
}
|
||||
if (!visited.has(toId)) return null;
|
||||
const path = [];
|
||||
let cur = toId;
|
||||
while (cur !== -1) { path.unshift(cur); cur = prev[cur]; }
|
||||
return path;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// PAGE GENERATION
|
||||
// ============================================================
|
||||
|
||||
function generatePage(config, pageIndex) {
|
||||
seedRng(config.seed); // deterministic output per page
|
||||
let nodes, edges, enemyRoute, playerRoute;
|
||||
let success = false;
|
||||
|
||||
for (let attempt = 0; attempt < 80; attempt++) {
|
||||
nodes = generateNodes();
|
||||
edges = generateEdges(nodes);
|
||||
|
||||
// Find corner starts
|
||||
const enemyStartNode = findCornerNode(nodes, 'top-left');
|
||||
const playerStartNode = findCornerNode(nodes, 'bottom-left');
|
||||
|
||||
// Trim start nodes to exactly 2 edges
|
||||
trimNodeDegree(nodes, edges, enemyStartNode.id, 2);
|
||||
trimNodeDegree(nodes, edges, playerStartNode.id, 2);
|
||||
|
||||
const [minVal, maxSpread] = config.diffRange;
|
||||
if (!assignValues(nodes, minVal, maxSpread)) continue;
|
||||
|
||||
// Enemy route: from top-left corner toward bottom-right area
|
||||
const targetArea = { x: MAP_RIGHT - 30, y: MAP_BOTTOM - 40 };
|
||||
enemyRoute = findDirectionalRoute(nodes, enemyStartNode.id, config.routeLength, targetArea);
|
||||
if (!enemyRoute) continue;
|
||||
|
||||
const dest = enemyRoute[enemyRoute.length - 1];
|
||||
|
||||
// Player route: from bottom-left corner to destination
|
||||
if (playerStartNode.id === dest || enemyRoute.includes(playerStartNode.id)) continue;
|
||||
playerRoute = findShortestPath(nodes, playerStartNode.id, dest);
|
||||
if (playerRoute && playerRoute.length >= 3) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
return `<div class="w-[210mm] h-[297mm] mx-auto bg-white flex items-center justify-center text-red-500 text-xl">Page ${pageIndex + 1}: Generation failed after 80 attempts</div>`;
|
||||
}
|
||||
|
||||
return renderPage(nodes, edges, enemyRoute, playerRoute, config, pageIndex);
|
||||
}
|
||||
|
||||
function renderPage(nodes, edges, enemyRoute, playerRoute, config, pageIndex) {
|
||||
const dest = enemyRoute[enemyRoute.length - 1];
|
||||
const enemyStart = enemyRoute[0];
|
||||
const playerStart = playerRoute[0];
|
||||
|
||||
// Pick nodes for decorative objects (not start/dest nodes, spread across map)
|
||||
const decoNodeIds = [];
|
||||
const usedIds = new Set([enemyStart, playerStart, dest, ...enemyRoute, ...playerRoute]);
|
||||
const availableNodes = nodes.filter(n => !usedIds.has(n.id));
|
||||
// Spread them out by picking from different y-regions
|
||||
const sortedByRegion = [...availableNodes].sort((a, b) => a.y - b.y);
|
||||
const regionSize = Math.floor(sortedByRegion.length / (config.decoObjects.length + 1));
|
||||
for (let di = 0; di < config.decoObjects.length; di++) {
|
||||
const regionStart = regionSize * (di + 0.5);
|
||||
const idx = Math.min(Math.floor(regionStart + randF(-2, 2)), sortedByRegion.length - 1);
|
||||
if (idx >= 0 && !decoNodeIds.includes(sortedByRegion[idx].id)) {
|
||||
decoNodeIds.push(sortedByRegion[Math.max(0, idx)].id);
|
||||
}
|
||||
}
|
||||
|
||||
// Build SVG for edges
|
||||
let edgeSvg = '';
|
||||
for (const e of edges) {
|
||||
const n1 = nodes[e.i], n2 = nodes[e.j];
|
||||
edgeSvg += `<line x1="${n1.x}mm" y1="${n1.y}mm" x2="${n2.x}mm" y2="${n2.y}mm"
|
||||
stroke="#a5b4fc" stroke-width="0.7" stroke-dasharray="2.5 2" stroke-linecap="round" opacity="0.45"/>`;
|
||||
}
|
||||
|
||||
// Build node circles
|
||||
const asteroidNodeIds = new Set([dest, ...decoNodeIds]);
|
||||
let nodesHtml = '';
|
||||
for (const n of nodes) {
|
||||
const isEnemyStart = n.id === enemyStart;
|
||||
const isPlayerStart = n.id === playerStart;
|
||||
const isStartNode = isEnemyStart || isPlayerStart;
|
||||
const hasAsteroid = asteroidNodeIds.has(n.id);
|
||||
|
||||
const borderWidth = isStartNode ? '2.5px' : '1.5px';
|
||||
const borderColor = isStartNode ? 'border-indigo-600' : 'border-indigo-300';
|
||||
const bgColor = isStartNode ? 'bg-indigo-50' : 'bg-white';
|
||||
const fontSize = isStartNode ? '13px' : '11px';
|
||||
const shadow = isStartNode ? 'shadow-md shadow-indigo-200' : 'shadow-sm';
|
||||
const baseSize = isStartNode ? NODE_R_MM * 2.4 : NODE_R_MM * 2;
|
||||
const size = hasAsteroid ? baseSize / 1.5 : baseSize;
|
||||
const offset = size / 2;
|
||||
|
||||
nodesHtml += `
|
||||
<div class="absolute flex items-center justify-center rounded-full ${borderColor} ${bgColor} ${shadow}"
|
||||
style="left:${n.x}mm;top:${n.y}mm;width:${size}mm;height:${size}mm;margin-left:-${offset}mm;margin-top:-${offset}mm;z-index:15;border-width:${borderWidth};">
|
||||
<span class="font-extrabold text-indigo-950 leading-none" style="font-size:${fontSize};">${n.value}</span>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// Destination object — large asteroid under the destination node
|
||||
const destNode = nodes[dest];
|
||||
let destObjHtml = `
|
||||
<img src="${config.destObjectImg}" class="absolute object-contain"
|
||||
style="left:${destNode.x}mm;top:${destNode.y}mm;width:30mm;height:30mm;margin-left:-15mm;margin-top:-15mm;z-index:4;" alt="">`;
|
||||
|
||||
// Decorative objects — placed under specific nodes, large
|
||||
let decosHtml = '';
|
||||
for (let di = 0; di < config.decoObjects.length && di < decoNodeIds.length; di++) {
|
||||
const dn = nodes[decoNodeIds[di]];
|
||||
decosHtml += `
|
||||
<img src="${config.decoObjects[di].img}" class="absolute object-contain"
|
||||
style="left:${dn.x}mm;top:${dn.y}mm;width:24mm;height:24mm;margin-left:-12mm;margin-top:-12mm;z-index:4;" alt="">`;
|
||||
}
|
||||
|
||||
// Decorative stars — bigger, darker, more
|
||||
let starsHtml = '';
|
||||
for (let i = 0; i < 70; i++) {
|
||||
const sx = randF(6, 204);
|
||||
const sy = randF(30, 270);
|
||||
const size = randF(10, 22);
|
||||
const opacity = randF(0.12, 0.35);
|
||||
const symbols = ['✦', '✧', '⋆', '·', '∗', '⊹'];
|
||||
starsHtml += `<span class="absolute text-indigo-300" style="left:${sx}mm;top:${sy}mm;font-size:${size}px;opacity:${opacity};z-index:2;pointer-events:none;">${symbols[rand(0, symbols.length - 1)]}</span>`;
|
||||
}
|
||||
|
||||
// Enemy route: circle with start value + diff cells
|
||||
const enemyDiffs = [];
|
||||
for (let i = 1; i < enemyRoute.length; i++) {
|
||||
enemyDiffs.push(nodes[enemyRoute[i]].value - nodes[enemyRoute[i - 1]].value);
|
||||
}
|
||||
|
||||
let enemyRouteCells = `<div class="inline-flex items-center justify-center rounded-full border-[2px] border-indigo-500 bg-indigo-50 shrink-0" style="width:8mm;height:8mm;">
|
||||
<span class="text-[12px] font-extrabold text-indigo-950">${nodes[enemyStart].value}</span>
|
||||
</div>`;
|
||||
for (const diff of enemyDiffs) {
|
||||
const diffStr = (diff > 0 ? '+' : '') + diff;
|
||||
enemyRouteCells += `<div class="inline-flex items-center justify-center shrink-0 border-[1.5px] border-indigo-300 rounded bg-white" style="width:9mm;height:7mm;margin-left:1mm;">
|
||||
<span class="text-[11px] font-bold text-indigo-950">${diffStr}</span>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// Player route: circle + 10 empty cells
|
||||
const cellCount = Math.max(PLAYER_ROUTE_CELLS, playerRoute.length - 1);
|
||||
let playerRouteCells = `<div class="inline-flex items-center justify-center rounded-full border-[2px] border-indigo-500 bg-indigo-50 shrink-0" style="width:8mm;height:8mm;">
|
||||
<span class="text-[12px] font-extrabold text-indigo-950">${nodes[playerStart].value}</span>
|
||||
</div>`;
|
||||
for (let i = 0; i < cellCount; i++) {
|
||||
playerRouteCells += `<div class="inline-flex items-center justify-center shrink-0 border-[1.5px] border-indigo-200 border-dashed rounded bg-white" style="width:9mm;height:7mm;margin-left:1mm;">
|
||||
</div>`;
|
||||
}
|
||||
|
||||
const isLastPage = pageIndex === PAGES.length - 1;
|
||||
const pageBreak = isLastPage ? '' : 'break-after: page;';
|
||||
|
||||
const [minVal, maxSpread] = config.diffRange;
|
||||
const nodeValues = nodes.map(n => n.value);
|
||||
const actualMin = Math.min(...nodeValues);
|
||||
const actualMax = Math.max(...nodeValues);
|
||||
|
||||
return `
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" style="${pageBreak}">
|
||||
|
||||
<!-- Footer with planet -->
|
||||
<div class="absolute bottom-0 left-0 right-0 h-[80mm] z-0">
|
||||
<div class="absolute top-0 left-0 right-0 h-full z-10" style="background: linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%);"></div>
|
||||
<img src="${config.footerImg}" class="w-full h-full object-cover object-top" alt="">
|
||||
</div>
|
||||
|
||||
<!-- Map content -->
|
||||
<div class="absolute inset-0" style="z-index:3;">
|
||||
|
||||
<!-- Stars -->
|
||||
${starsHtml}
|
||||
|
||||
<!-- Destination object -->
|
||||
${destObjHtml}
|
||||
|
||||
<!-- Decorative objects -->
|
||||
${decosHtml}
|
||||
|
||||
<!-- Edges SVG -->
|
||||
<svg class="absolute inset-0 w-full h-full" style="z-index:5;" xmlns="http://www.w3.org/2000/svg">
|
||||
${edgeSvg}
|
||||
</svg>
|
||||
|
||||
<!-- Nodes -->
|
||||
${nodesHtml}
|
||||
|
||||
<!-- Header with enemy ship -->
|
||||
<div class="absolute top-0 left-0 right-0 z-30">
|
||||
<div class="flex items-start">
|
||||
<!-- Enemy ship image — 40% of header -->
|
||||
<img src="${config.enemyShipImg}" class="shrink-0 object-contain" style="width:48%;max-height:50mm;z-index:4;${config.flipEnemy ? 'transform:scaleX(-1);' : ''}" alt="">
|
||||
<!-- Title — right side -->
|
||||
<div class="flex-1 flex flex-col items-center justify-center text-center pt-[5mm]">
|
||||
<h1 class="text-[1.4rem] font-extrabold leading-tight tracking-tight text-indigo-950">Проложи Маршрут</h1>
|
||||
<p class="text-[0.75rem] font-medium text-indigo-300 mt-0">Найди путь в космосе!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Enemy route card (right side, under title) -->
|
||||
<div class="absolute z-30" style="top:19mm;right:8mm;">
|
||||
<div class="flex items-center gap-[2mm] px-[3mm] py-[1.5mm] rounded-lg border-[1.5px] border-indigo-100" style="background:rgba(255,255,255,0.75);">
|
||||
<div class="text-[11px] font-bold text-indigo-900 whitespace-nowrap">${config.enemyLabel}:</div>
|
||||
<div class="flex items-center flex-nowrap">${enemyRouteCells}</div>
|
||||
</div>
|
||||
<div class="text-[10px] text-indigo-400 mt-[0.5mm] text-right pr-[2mm]">📍 Проследи маршрут — куда он летит?</div>
|
||||
</div>
|
||||
|
||||
<!-- Player ship image (over footer, left side) -->
|
||||
<img src="${config.playerShipImg}" class="absolute object-contain" style="bottom:8mm;left:0;width:48%;max-height:60mm;z-index:4;${config.flipPlayer ? 'transform:scaleX(-1);' : ''}" alt="">
|
||||
|
||||
<!-- Player route card (right side) -->
|
||||
<div class="absolute z-30" style="bottom:14mm;right:8mm;">
|
||||
<div class="text-[12px] font-semibold text-gray-800 mb-[1mm] text-right pr-[2mm]">Рассчитай маршрут до цели перехвата</div>
|
||||
<div class="flex items-center gap-[2mm] px-[3mm] py-[1.5mm] rounded-lg border-[1.5px] border-indigo-100" style="background:rgba(255,255,255,0.75);">
|
||||
<div class="text-[11px] font-bold text-indigo-900 whitespace-nowrap">Твой истребитель:</div>
|
||||
<div class="flex items-center flex-nowrap">${playerRouteCells}</div>
|
||||
</div>
|
||||
<div class="text-[12px] font-semibold text-gray-800 mt-[1mm] text-right pr-[2mm]">✏️ Запиши разницу чисел, чтобы добраться до цели!</div>
|
||||
</div>
|
||||
|
||||
<!-- Debug info -->
|
||||
<div class="absolute z-40 text-[7px] text-indigo-300" style="bottom:3mm;left:3mm;">
|
||||
[${minVal},${maxSpread}] | ${nodes.length} nodes | values ${actualMin}-${actualMax} | enemy ${enemyRoute.length} steps | player shortest ${playerRoute.length - 1} steps
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// GENERATE ALL PAGES
|
||||
// ============================================================
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
let html = '';
|
||||
for (let i = 0; i < PAGES.length; i++) {
|
||||
html += generatePage(PAGES[i], i);
|
||||
}
|
||||
document.body.innerHTML = html;
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,792 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Space Route Editor</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { background: #1e1e2e; color: #cdd6f4; font-family: 'Segoe UI', system-ui, sans-serif; }
|
||||
|
||||
#toolbar {
|
||||
position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
|
||||
background: #181825; border-bottom: 1px solid #313244;
|
||||
display: flex; align-items: center; gap: 8px; padding: 8px 12px; height: 48px;
|
||||
flex-wrap: nowrap; overflow-x: auto;
|
||||
}
|
||||
#toolbar button {
|
||||
background: #313244; color: #cdd6f4; border: 1px solid #45475a;
|
||||
padding: 5px 10px; border-radius: 6px; cursor: pointer; font-size: 12px;
|
||||
transition: background 0.15s; white-space: nowrap;
|
||||
}
|
||||
#toolbar button:hover { background: #45475a; }
|
||||
#toolbar button.primary { background: #6366f1; border-color: #818cf8; color: white; }
|
||||
#toolbar button.primary:hover { background: #818cf8; }
|
||||
#toolbar button.active { background: #f59e0b; border-color: #fbbf24; color: #1e1e2e; }
|
||||
#toolbar .page-nav { display: flex; align-items: center; gap: 4px; }
|
||||
#toolbar .page-nav span { font-size: 13px; min-width: 80px; text-align: center; }
|
||||
#toolbar .spacer { flex: 1; }
|
||||
#toolbar .sep { width: 1px; height: 24px; background: #45475a; }
|
||||
#toolbar .title { font-weight: 600; font-size: 13px; color: #a6adc8; }
|
||||
|
||||
#statusbar {
|
||||
position: fixed; bottom: 0; left: 0; right: 0; z-index: 1000;
|
||||
background: #181825; border-top: 1px solid #313244;
|
||||
padding: 6px 16px; font-size: 12px; height: 32px;
|
||||
display: flex; align-items: center; gap: 16px;
|
||||
}
|
||||
#statusbar .pos { color: #89b4fa; }
|
||||
#statusbar .info { color: #a6adc8; }
|
||||
#statusbar .keys { color: #6c7086; font-size: 11px; }
|
||||
|
||||
#worksheet-container {
|
||||
padding: 56px 0 32px;
|
||||
display: flex; flex-direction: column; align-items: center; gap: 20px;
|
||||
}
|
||||
|
||||
.obj-draggable { cursor: grab; user-select: none; z-index: 20 !important; position: absolute; }
|
||||
/* In node mode, objects become click-through */
|
||||
body.node-mode .obj-draggable { pointer-events: none !important; z-index: 4 !important; }
|
||||
body.node-mode .node-draggable { z-index: 20 !important; cursor: grab; }
|
||||
.obj-draggable:hover { outline: 2px solid rgba(99, 102, 241, 0.6); outline-offset: 2px; }
|
||||
.obj-selected { outline: 3px solid #6366f1 !important; outline-offset: 2px; }
|
||||
.obj-changed::after {
|
||||
content: ''; position: absolute; top: -2px; right: -2px;
|
||||
width: 8px; height: 8px; background: #f59e0b; border-radius: 50%;
|
||||
border: 1px solid #1e1e2e; z-index: 100;
|
||||
}
|
||||
/* Node dragging (Shift+click) */
|
||||
.node-draggable { cursor: grab; user-select: none; }
|
||||
.node-draggable:hover { box-shadow: 0 0 0 3px rgba(251, 191, 36, 0.4) !important; }
|
||||
.node-selected { box-shadow: 0 0 0 3px #f59e0b !important; }
|
||||
.node-changed { box-shadow: 0 0 0 2px #f59e0b, 0 0 8px rgba(251, 191, 36, 0.3) !important; }
|
||||
body.dragging, body.dragging * { cursor: grabbing !important; }
|
||||
|
||||
#coord-tooltip {
|
||||
position: fixed; z-index: 2000; pointer-events: none;
|
||||
background: #181825; color: #89b4fa; border: 1px solid #6366f1;
|
||||
padding: 3px 8px; border-radius: 4px; font-size: 12px; font-family: monospace;
|
||||
display: none;
|
||||
}
|
||||
#toast {
|
||||
position: fixed; top: 60px; right: 16px; z-index: 2000;
|
||||
background: #6366f1; color: white; padding: 8px 16px; border-radius: 6px;
|
||||
font-size: 13px; opacity: 0; transition: opacity 0.3s; pointer-events: none;
|
||||
}
|
||||
#toast.show { opacity: 1; }
|
||||
.page-label {
|
||||
position: absolute; top: 4px; right: 4px; z-index: 100;
|
||||
background: rgba(0,0,0,0.6); color: white; padding: 2px 8px;
|
||||
border-radius: 4px; font-size: 12px; pointer-events: none;
|
||||
}
|
||||
/* Route highlight */
|
||||
line.route-highlight {
|
||||
stroke: #f87171 !important; stroke-width: 2.5 !important;
|
||||
opacity: 0.8 !important; stroke-dasharray: none !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="toolbar">
|
||||
<span class="title">Route Editor</span>
|
||||
<div class="page-nav">
|
||||
<button id="btn-prev">←</button>
|
||||
<span id="page-indicator">Page 1 / ?</span>
|
||||
<button id="btn-next">→</button>
|
||||
</div>
|
||||
<div class="sep"></div>
|
||||
<button id="btn-mode" title="Switch between Objects and Nodes mode (M)">Mode: Objects</button>
|
||||
<button id="btn-route" title="Toggle enemy route highlight">Route HL</button>
|
||||
<button id="btn-flip" title="Flip selected object horizontally (H)">Flip H</button>
|
||||
<div class="sep"></div>
|
||||
<button id="btn-reset">Reset Page</button>
|
||||
<button id="btn-copy-changes">Copy Changes</button>
|
||||
<button id="btn-copy" class="primary">Copy All JSON</button>
|
||||
<button id="btn-save" class="primary" style="background:#22c55e;border-color:#4ade80;">Save</button>
|
||||
</div>
|
||||
|
||||
<div id="worksheet-container"></div>
|
||||
|
||||
<div id="statusbar">
|
||||
<span id="status-info" class="info">Click an object to select</span>
|
||||
<span id="status-pos" class="pos"></span>
|
||||
<span class="keys">M: switch mode | Arrows: move | [ ] rotate | - + scale | H: flip | R: route</span>
|
||||
</div>
|
||||
|
||||
<div id="coord-tooltip"></div>
|
||||
<div id="toast"></div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const params = new URLSearchParams(location.search);
|
||||
const fileParam = params.get('file') || 'space-route-1';
|
||||
const file = 'docs/' + fileParam + '.template.html';
|
||||
const docId = fileParam;
|
||||
|
||||
let pages = [];
|
||||
let objects = []; // draggable objects (images with data-node-id)
|
||||
let nodeEls = []; // all node divs
|
||||
let originalState = new Map(); // obj originals
|
||||
let nodeOrigState = new Map(); // node originals
|
||||
let selectedObj = null; // selected object OR node
|
||||
let selectedType = null; // 'obj' or 'node'
|
||||
let dragging = null;
|
||||
let dragStart = null;
|
||||
let mmToPx = 1;
|
||||
let currentPage = 0;
|
||||
let routeHighlight = false;
|
||||
let editMode = 'objects'; // 'objects' or 'nodes'
|
||||
|
||||
fetch(file)
|
||||
.then(r => { if (!r.ok) throw new Error(r.status); return r.text(); })
|
||||
.then(html => {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(html, 'text/html');
|
||||
const container = document.getElementById('worksheet-container');
|
||||
|
||||
const tw = document.createElement('script');
|
||||
tw.src = 'https://cdn.tailwindcss.com';
|
||||
document.head.appendChild(tw);
|
||||
|
||||
doc.querySelectorAll('head script:not([src])').forEach(s => {
|
||||
const ns = document.createElement('script');
|
||||
ns.textContent = s.textContent;
|
||||
document.head.appendChild(ns);
|
||||
});
|
||||
doc.querySelectorAll('head style').forEach(s => {
|
||||
const ns = document.createElement('style');
|
||||
ns.textContent = s.textContent;
|
||||
document.head.appendChild(ns);
|
||||
});
|
||||
doc.querySelectorAll('head link').forEach(l => {
|
||||
document.head.appendChild(l.cloneNode(true));
|
||||
});
|
||||
|
||||
container.innerHTML = doc.body.innerHTML;
|
||||
setTimeout(() => initEditor(), 400);
|
||||
})
|
||||
.catch(err => {
|
||||
document.getElementById('worksheet-container').innerHTML =
|
||||
`<p style="padding:80px 20px;color:#f38ba8;">Failed to load ${file}: ${err.message}</p>`;
|
||||
});
|
||||
|
||||
function initEditor() {
|
||||
pages = Array.from(document.querySelectorAll('.w-\\[210mm\\]'));
|
||||
pages.forEach((p, i) => {
|
||||
p.dataset.page = i + 1;
|
||||
p.style.position = 'relative';
|
||||
const label = document.createElement('div');
|
||||
label.className = 'page-label';
|
||||
label.textContent = `Page ${i + 1}`;
|
||||
p.appendChild(label);
|
||||
});
|
||||
|
||||
document.getElementById('page-indicator').textContent = `Page 1 / ${pages.length}`;
|
||||
|
||||
if (pages.length > 0) {
|
||||
mmToPx = pages[0].getBoundingClientRect().width / 210;
|
||||
}
|
||||
|
||||
// Find all space objects (images with data-node-id)
|
||||
document.querySelectorAll('img.space-obj').forEach((img, idx) => {
|
||||
const page = img.closest('[data-page]');
|
||||
const pageNum = page ? parseInt(page.dataset.page) : 0;
|
||||
const nodeId = img.dataset.nodeId;
|
||||
|
||||
// Wrap in a container div for positioning if not already
|
||||
// Objects are already absolutely positioned images
|
||||
const left = parseFloat(img.style.left) || 0;
|
||||
const top = parseFloat(img.style.top) || 0;
|
||||
const w = parseFloat(img.style.width) || 24;
|
||||
const h = parseFloat(img.style.height) || 24;
|
||||
|
||||
// Parse transform
|
||||
let rotate = 0, scaleX = 1, scaleY = 1;
|
||||
if (img.style.transform) {
|
||||
const rotM = img.style.transform.match(/rotate\(([-\d.]+)deg\)/);
|
||||
const scxM = img.style.transform.match(/scaleX\(([-\d.]+)\)/);
|
||||
const scyM = img.style.transform.match(/scaleY\(([-\d.]+)\)/);
|
||||
const scM = img.style.transform.match(/scale\(([-\d.]+)\)/);
|
||||
if (rotM) rotate = parseFloat(rotM[1]);
|
||||
if (scxM) scaleX = parseFloat(scxM[1]);
|
||||
if (scyM) scaleY = parseFloat(scyM[1]);
|
||||
if (scM) scaleX = scaleY = parseFloat(scM[1]);
|
||||
}
|
||||
|
||||
const id = `p${pageNum}-obj${idx}`;
|
||||
img.dataset.objId = id;
|
||||
img.dataset.pageNum = pageNum;
|
||||
img.style.position = 'absolute';
|
||||
|
||||
originalState.set(id, { left, top, w, h, rotate, scaleX, scaleY });
|
||||
|
||||
img.classList.add('obj-draggable');
|
||||
img.draggable = false;
|
||||
|
||||
objects.push({
|
||||
el: img, id, pageNum, nodeId,
|
||||
type: img.dataset.type,
|
||||
src: img.src.split('/').pop()
|
||||
});
|
||||
|
||||
img.addEventListener('mousedown', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
selectObj(img, id);
|
||||
startDrag(img, e);
|
||||
});
|
||||
});
|
||||
|
||||
// Init nodes (Shift+click to select)
|
||||
document.querySelectorAll('[data-node-id]').forEach(nodeDiv => {
|
||||
if (nodeDiv.tagName === 'IMG') return; // skip objects, only div nodes
|
||||
const page = nodeDiv.closest('[data-page]');
|
||||
const pageNum = page ? parseInt(page.dataset.page) : 0;
|
||||
const nodeId = nodeDiv.dataset.nodeId;
|
||||
const left = parseFloat(nodeDiv.style.left) || 0;
|
||||
const top = parseFloat(nodeDiv.style.top) || 0;
|
||||
const nid = `p${pageNum}-n${nodeId}`;
|
||||
nodeDiv.dataset.nid = nid;
|
||||
nodeDiv.dataset.pageNum = pageNum;
|
||||
|
||||
nodeOrigState.set(nid, { left, top });
|
||||
nodeDiv.classList.add('node-draggable');
|
||||
|
||||
nodeEls.push({ el: nodeDiv, nid, pageNum, nodeId });
|
||||
|
||||
nodeDiv.addEventListener('mousedown', (e) => {
|
||||
if (editMode !== 'nodes') return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
selectNode(nodeDiv, nid);
|
||||
startDrag(nodeDiv, e);
|
||||
});
|
||||
});
|
||||
|
||||
// Page scroll tracking
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting && entry.intersectionRatio > 0.3) {
|
||||
currentPage = parseInt(entry.target.dataset.page) - 1;
|
||||
document.getElementById('page-indicator').textContent =
|
||||
`Page ${currentPage + 1} / ${pages.length}`;
|
||||
}
|
||||
});
|
||||
}, { threshold: [0.3] });
|
||||
pages.forEach(p => observer.observe(p));
|
||||
|
||||
document.addEventListener('mousemove', onMouseMove);
|
||||
document.addEventListener('mouseup', onMouseUp);
|
||||
|
||||
document.getElementById('worksheet-container').addEventListener('mousedown', (e) => {
|
||||
if (!e.target.closest('.obj-draggable')) deselectAll();
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', onKeyDown);
|
||||
|
||||
document.getElementById('btn-prev').addEventListener('click', () => scrollToPage(currentPage - 1));
|
||||
document.getElementById('btn-next').addEventListener('click', () => scrollToPage(currentPage + 1));
|
||||
document.getElementById('btn-copy').addEventListener('click', () => copyConfig(false));
|
||||
document.getElementById('btn-copy-changes').addEventListener('click', () => copyConfig(true));
|
||||
document.getElementById('btn-reset').addEventListener('click', resetCurrentPage);
|
||||
document.getElementById('btn-flip').addEventListener('click', flipSelected);
|
||||
document.getElementById('btn-mode').addEventListener('click', toggleMode);
|
||||
document.getElementById('btn-route').addEventListener('click', toggleRouteHL);
|
||||
document.getElementById('btn-save').addEventListener('click', saveToServer);
|
||||
|
||||
window.getConfig = () => buildConfig(false);
|
||||
window.getChanges = () => buildConfig(true);
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
if (pages.length > 0) mmToPx = pages[0].getBoundingClientRect().width / 210;
|
||||
});
|
||||
}
|
||||
|
||||
function selectObj(el, id) {
|
||||
deselectAll();
|
||||
el.classList.add('obj-selected');
|
||||
selectedObj = el;
|
||||
selectedType = 'obj';
|
||||
updateStatus(el, id);
|
||||
}
|
||||
|
||||
function selectNode(el, nid) {
|
||||
deselectAll();
|
||||
el.classList.add('node-selected');
|
||||
selectedObj = el;
|
||||
selectedType = 'node';
|
||||
const left = parseFloat(el.style.left).toFixed(1);
|
||||
const top = parseFloat(el.style.top).toFixed(1);
|
||||
const val = el.querySelector('span')?.textContent || '?';
|
||||
document.getElementById('status-info').textContent =
|
||||
`NODE | Page ${el.dataset.pageNum} | id:${el.dataset.nodeId} | value:${val}`;
|
||||
document.getElementById('status-pos').textContent = `pos: ${left}, ${top}mm`;
|
||||
}
|
||||
|
||||
function deselectAll() {
|
||||
document.querySelectorAll('.obj-selected').forEach(el => el.classList.remove('obj-selected'));
|
||||
document.querySelectorAll('.node-selected').forEach(el => el.classList.remove('node-selected'));
|
||||
selectedObj = null;
|
||||
selectedType = null;
|
||||
document.getElementById('status-info').textContent = 'Click object / Shift+click node';
|
||||
document.getElementById('status-pos').textContent = '';
|
||||
}
|
||||
|
||||
function updateStatus(el, id) {
|
||||
const left = parseFloat(el.style.left).toFixed(1);
|
||||
const top = parseFloat(el.style.top).toFixed(1);
|
||||
const w = parseFloat(el.style.width).toFixed(0);
|
||||
const h = parseFloat(el.style.height).toFixed(0);
|
||||
const obj = objects.find(o => o.id === id);
|
||||
const page = el.dataset.pageNum || '?';
|
||||
|
||||
let rotStr = '0', flipStr = '';
|
||||
if (el.style.transform) {
|
||||
const rotM = el.style.transform.match(/rotate\(([-\d.]+)deg\)/);
|
||||
const scxM = el.style.transform.match(/scaleX\(([-\d.]+)\)/);
|
||||
if (rotM) rotStr = Math.round(parseFloat(rotM[1]));
|
||||
if (scxM && parseFloat(scxM[1]) < 0) flipStr = ' FLIP';
|
||||
}
|
||||
|
||||
document.getElementById('status-info').textContent =
|
||||
`Page ${page} | node:${obj?.nodeId} | ${obj?.src || ''}`;
|
||||
document.getElementById('status-pos').textContent =
|
||||
`pos: ${left}, ${top}mm | size: ${w}×${h}mm | rot: ${rotStr}°${flipStr}`;
|
||||
}
|
||||
|
||||
// Move the corresponding node and connected edges when an object moves
|
||||
function moveNodeAndEdges(el, newLeft, newTop) {
|
||||
const nodeId = el.dataset.nodeId;
|
||||
if (!nodeId) return;
|
||||
|
||||
const page = el.closest('[data-page]');
|
||||
if (!page) return;
|
||||
|
||||
// Find the node div
|
||||
const nodeDiv = page.querySelector(`[data-node-id="${nodeId}"]`);
|
||||
if (nodeDiv) {
|
||||
nodeDiv.style.left = newLeft.toFixed(1) + 'mm';
|
||||
nodeDiv.style.top = newTop.toFixed(1) + 'mm';
|
||||
}
|
||||
|
||||
// Update all edges connected to this node
|
||||
const svg = page.querySelector('svg');
|
||||
if (!svg) return;
|
||||
|
||||
svg.querySelectorAll(`line[data-edge]`).forEach(line => {
|
||||
const [a, b] = line.dataset.edge.split('-');
|
||||
if (a === nodeId) {
|
||||
line.setAttribute('x1', newLeft.toFixed(1) + 'mm');
|
||||
line.setAttribute('y1', newTop.toFixed(1) + 'mm');
|
||||
}
|
||||
if (b === nodeId) {
|
||||
line.setAttribute('x2', newLeft.toFixed(1) + 'mm');
|
||||
line.setAttribute('y2', newTop.toFixed(1) + 'mm');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Move only edges for a node (without moving the node itself — used when dragging node directly)
|
||||
function moveEdgesForNode(nodeDiv, newLeft, newTop) {
|
||||
const nodeId = nodeDiv.dataset.nodeId;
|
||||
const page = nodeDiv.closest('[data-page]');
|
||||
if (!page) return;
|
||||
const svg = page.querySelector('svg');
|
||||
if (!svg) return;
|
||||
svg.querySelectorAll('line[data-edge]').forEach(line => {
|
||||
const [a, b] = line.dataset.edge.split('-');
|
||||
if (a === nodeId) {
|
||||
line.setAttribute('x1', newLeft.toFixed(1) + 'mm');
|
||||
line.setAttribute('y1', newTop.toFixed(1) + 'mm');
|
||||
}
|
||||
if (b === nodeId) {
|
||||
line.setAttribute('x2', newLeft.toFixed(1) + 'mm');
|
||||
line.setAttribute('y2', newTop.toFixed(1) + 'mm');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function markNodeChanged(nodeDiv) {
|
||||
const nid = nodeDiv.dataset.nid;
|
||||
const orig = nodeOrigState.get(nid);
|
||||
if (!orig) return;
|
||||
const curLeft = parseFloat(nodeDiv.style.left);
|
||||
const curTop = parseFloat(nodeDiv.style.top);
|
||||
const changed = Math.abs(orig.left - curLeft) > 0.3 || Math.abs(orig.top - curTop) > 0.3;
|
||||
nodeDiv.classList.toggle('node-changed', changed);
|
||||
}
|
||||
|
||||
function startDrag(el, e) {
|
||||
dragging = el;
|
||||
dragStart = {
|
||||
mouseX: e.clientX, mouseY: e.clientY,
|
||||
left: parseFloat(el.style.left) || 0,
|
||||
top: parseFloat(el.style.top) || 0
|
||||
};
|
||||
document.body.classList.add('dragging');
|
||||
document.getElementById('coord-tooltip').style.display = 'block';
|
||||
}
|
||||
|
||||
function onMouseMove(e) {
|
||||
if (!dragging) return;
|
||||
e.preventDefault();
|
||||
|
||||
const dx = (e.clientX - dragStart.mouseX) / mmToPx;
|
||||
const dy = (e.clientY - dragStart.mouseY) / mmToPx;
|
||||
|
||||
const newLeft = Math.round((dragStart.left + dx) * 2) / 2;
|
||||
const newTop = Math.round((dragStart.top + dy) * 2) / 2;
|
||||
|
||||
dragging.style.left = newLeft.toFixed(1) + 'mm';
|
||||
dragging.style.top = newTop.toFixed(1) + 'mm';
|
||||
|
||||
if (selectedType === 'obj') {
|
||||
// Update margin to keep object centered
|
||||
const w = parseFloat(dragging.style.width) || 24;
|
||||
const h = parseFloat(dragging.style.height) || 24;
|
||||
dragging.style.marginLeft = (-w / 2) + 'mm';
|
||||
dragging.style.marginTop = (-h / 2) + 'mm';
|
||||
updateStatus(dragging, dragging.dataset.objId);
|
||||
markChanged(dragging);
|
||||
} else if (selectedType === 'node') {
|
||||
// Update margin for node centering
|
||||
const size = parseFloat(dragging.style.width) || 10;
|
||||
dragging.style.marginLeft = (-size / 2) + 'mm';
|
||||
dragging.style.marginTop = (-size / 2) + 'mm';
|
||||
// Move connected edges
|
||||
moveEdgesForNode(dragging, newLeft, newTop);
|
||||
markNodeChanged(dragging);
|
||||
// Update status
|
||||
const val = dragging.querySelector('span')?.textContent || '?';
|
||||
document.getElementById('status-info').textContent =
|
||||
`NODE | Page ${dragging.dataset.pageNum} | id:${dragging.dataset.nodeId} | value:${val}`;
|
||||
document.getElementById('status-pos').textContent = `pos: ${newLeft.toFixed(1)}, ${newTop.toFixed(1)}mm`;
|
||||
}
|
||||
|
||||
const tooltip = document.getElementById('coord-tooltip');
|
||||
tooltip.textContent = `${newLeft.toFixed(1)}, ${newTop.toFixed(1)}mm`;
|
||||
tooltip.style.left = (e.clientX + 15) + 'px';
|
||||
tooltip.style.top = (e.clientY - 10) + 'px';
|
||||
}
|
||||
|
||||
function onMouseUp() {
|
||||
if (!dragging) return;
|
||||
document.body.classList.remove('dragging');
|
||||
document.getElementById('coord-tooltip').style.display = 'none';
|
||||
dragging = null;
|
||||
dragStart = null;
|
||||
}
|
||||
|
||||
function onKeyDown(e) {
|
||||
if (e.key === 'm' || e.key === 'M') { toggleMode(); return; }
|
||||
if (e.key === 'r' || e.key === 'R') { toggleRouteHL(); return; }
|
||||
if (e.key === 'h' || e.key === 'H') { if (selectedType === 'obj') flipSelected(); return; }
|
||||
if (e.key === 'Escape') { deselectAll(); return; }
|
||||
|
||||
if (!selectedObj) return;
|
||||
|
||||
// Node mode: only arrows
|
||||
if (selectedType === 'node') {
|
||||
const step = e.shiftKey ? 5 : 1;
|
||||
let left = parseFloat(selectedObj.style.left) || 0;
|
||||
let top = parseFloat(selectedObj.style.top) || 0;
|
||||
switch (e.key) {
|
||||
case 'ArrowLeft': left -= step; break;
|
||||
case 'ArrowRight': left += step; break;
|
||||
case 'ArrowUp': top -= step; break;
|
||||
case 'ArrowDown': top += step; break;
|
||||
default: return;
|
||||
}
|
||||
e.preventDefault();
|
||||
selectedObj.style.left = left.toFixed(1) + 'mm';
|
||||
selectedObj.style.top = top.toFixed(1) + 'mm';
|
||||
const size = parseFloat(selectedObj.style.width) || 10;
|
||||
selectedObj.style.marginLeft = (-size / 2) + 'mm';
|
||||
selectedObj.style.marginTop = (-size / 2) + 'mm';
|
||||
moveEdgesForNode(selectedObj, left, top);
|
||||
markNodeChanged(selectedObj);
|
||||
const val = selectedObj.querySelector('span')?.textContent || '?';
|
||||
document.getElementById('status-pos').textContent = `pos: ${left.toFixed(1)}, ${top.toFixed(1)}mm`;
|
||||
return;
|
||||
}
|
||||
|
||||
// Object mode: arrows + rotate + resize
|
||||
const step = e.shiftKey ? 5 : 1;
|
||||
let left = parseFloat(selectedObj.style.left) || 0;
|
||||
let top = parseFloat(selectedObj.style.top) || 0;
|
||||
let w = parseFloat(selectedObj.style.width) || 24;
|
||||
let h = parseFloat(selectedObj.style.height) || 24;
|
||||
const sizeStep = e.shiftKey ? 1 : 2;
|
||||
const rotStep = e.shiftKey ? 1 : 5;
|
||||
|
||||
switch (e.key) {
|
||||
case 'ArrowLeft': left -= step; break;
|
||||
case 'ArrowRight': left += step; break;
|
||||
case 'ArrowUp': top -= step; break;
|
||||
case 'ArrowDown': top += step; break;
|
||||
case '[': applyRotate(selectedObj, -rotStep); break;
|
||||
case ']': applyRotate(selectedObj, rotStep); break;
|
||||
case '-': case '_':
|
||||
w = Math.max(8, w - sizeStep);
|
||||
h = Math.max(8, h - sizeStep * (h / w));
|
||||
selectedObj.style.width = w + 'mm';
|
||||
selectedObj.style.height = h + 'mm';
|
||||
selectedObj.style.marginLeft = (-w / 2) + 'mm';
|
||||
selectedObj.style.marginTop = (-h / 2) + 'mm';
|
||||
break;
|
||||
case '=': case '+':
|
||||
w = Math.min(60, w + sizeStep);
|
||||
h = Math.min(60, h + sizeStep * (h / w));
|
||||
selectedObj.style.width = w + 'mm';
|
||||
selectedObj.style.height = h + 'mm';
|
||||
selectedObj.style.marginLeft = (-w / 2) + 'mm';
|
||||
selectedObj.style.marginTop = (-h / 2) + 'mm';
|
||||
break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
selectedObj.style.left = left.toFixed(1) + 'mm';
|
||||
selectedObj.style.top = top.toFixed(1) + 'mm';
|
||||
selectedObj.style.marginLeft = (-parseFloat(selectedObj.style.width) / 2) + 'mm';
|
||||
selectedObj.style.marginTop = (-parseFloat(selectedObj.style.height) / 2) + 'mm';
|
||||
|
||||
updateStatus(selectedObj, selectedObj.dataset.objId);
|
||||
markChanged(selectedObj);
|
||||
}
|
||||
|
||||
function applyRotate(el, delta) {
|
||||
let transform = el.style.transform || '';
|
||||
const rotM = transform.match(/rotate\(([-\d.]+)deg\)/);
|
||||
let rot = rotM ? parseFloat(rotM[1]) : 0;
|
||||
rot += delta;
|
||||
if (rotM) {
|
||||
transform = transform.replace(/rotate\([-\d.]+deg\)/, `rotate(${rot}deg)`);
|
||||
} else {
|
||||
transform += ` rotate(${rot}deg)`;
|
||||
}
|
||||
el.style.transform = transform.trim();
|
||||
markChanged(el);
|
||||
}
|
||||
|
||||
function flipSelected() {
|
||||
if (!selectedObj) return;
|
||||
let transform = selectedObj.style.transform || '';
|
||||
const scxM = transform.match(/scaleX\(([-\d.]+)\)/);
|
||||
let scx = scxM ? parseFloat(scxM[1]) : 1;
|
||||
scx = scx < 0 ? 1 : -1;
|
||||
if (scxM) {
|
||||
transform = transform.replace(/scaleX\([-\d.]+\)/, `scaleX(${scx})`);
|
||||
} else {
|
||||
transform += ` scaleX(${scx})`;
|
||||
}
|
||||
selectedObj.style.transform = transform.trim();
|
||||
updateStatus(selectedObj, selectedObj.dataset.objId);
|
||||
markChanged(selectedObj);
|
||||
}
|
||||
|
||||
function toggleMode() {
|
||||
deselectAll();
|
||||
editMode = editMode === 'objects' ? 'nodes' : 'objects';
|
||||
document.body.classList.toggle('node-mode', editMode === 'nodes');
|
||||
const btn = document.getElementById('btn-mode');
|
||||
btn.textContent = editMode === 'objects' ? 'Mode: Objects' : 'Mode: Nodes';
|
||||
btn.classList.toggle('active', editMode === 'nodes');
|
||||
document.getElementById('status-info').textContent =
|
||||
editMode === 'objects' ? 'Click an object to select' : 'Click a node to select';
|
||||
}
|
||||
|
||||
function toggleRouteHL() {
|
||||
routeHighlight = !routeHighlight;
|
||||
const btn = document.getElementById('btn-route');
|
||||
btn.classList.toggle('active', routeHighlight);
|
||||
|
||||
pages.forEach(pageEl => {
|
||||
const routeStr = pageEl.dataset.enemyRoute;
|
||||
if (!routeStr) return;
|
||||
const route = routeStr.split(',');
|
||||
|
||||
// Build set of edge keys on the route
|
||||
const routeEdges = new Set();
|
||||
for (let i = 0; i < route.length - 1; i++) {
|
||||
const a = parseInt(route[i]), b = parseInt(route[i + 1]);
|
||||
routeEdges.add(`${Math.min(a, b)}-${Math.max(a, b)}`);
|
||||
}
|
||||
|
||||
pageEl.querySelectorAll('line[data-edge]').forEach(line => {
|
||||
const [ea, eb] = line.dataset.edge.split('-').map(Number);
|
||||
const key = `${Math.min(ea, eb)}-${Math.max(ea, eb)}`;
|
||||
if (routeEdges.has(key)) {
|
||||
line.classList.toggle('route-highlight', routeHighlight);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function markChanged(el) {
|
||||
const id = el.dataset.objId;
|
||||
const orig = originalState.get(id);
|
||||
if (!orig) return;
|
||||
const curLeft = parseFloat(el.style.left);
|
||||
const curTop = parseFloat(el.style.top);
|
||||
const curW = parseFloat(el.style.width);
|
||||
const curH = parseFloat(el.style.height);
|
||||
const changed = (
|
||||
Math.abs(orig.left - curLeft) > 0.3 ||
|
||||
Math.abs(orig.top - curTop) > 0.3 ||
|
||||
Math.abs(orig.w - curW) > 0.3 ||
|
||||
Math.abs(orig.h - curH) > 0.3 ||
|
||||
(el.style.transform || '') !== buildOrigTransform(orig)
|
||||
);
|
||||
el.classList.toggle('obj-changed', changed);
|
||||
}
|
||||
|
||||
function buildOrigTransform(orig) {
|
||||
let t = '';
|
||||
if (orig.scaleX < 0) t += `scaleX(${orig.scaleX})`;
|
||||
if (orig.rotate) t += ` rotate(${orig.rotate}deg)`;
|
||||
return t.trim();
|
||||
}
|
||||
|
||||
function scrollToPage(index) {
|
||||
if (index < 0 || index >= pages.length) return;
|
||||
pages[index].scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
|
||||
function buildConfig(changesOnly) {
|
||||
const result = { file, pages: [] };
|
||||
|
||||
pages.forEach((pageEl, pageIndex) => {
|
||||
const pageObjs = objects.filter(o => o.pageNum === pageIndex + 1);
|
||||
const items = [];
|
||||
|
||||
pageObjs.forEach(obj => {
|
||||
const el = obj.el;
|
||||
const left = parseFloat(el.style.left);
|
||||
const top = parseFloat(el.style.top);
|
||||
const w = parseFloat(el.style.width);
|
||||
const h = parseFloat(el.style.height);
|
||||
|
||||
let rotate = 0, flipH = false;
|
||||
if (el.style.transform) {
|
||||
const rotM = el.style.transform.match(/rotate\(([-\d.]+)deg\)/);
|
||||
const scxM = el.style.transform.match(/scaleX\(([-\d.]+)\)/);
|
||||
if (rotM) rotate = Math.round(parseFloat(rotM[1]));
|
||||
if (scxM && parseFloat(scxM[1]) < 0) flipH = true;
|
||||
}
|
||||
|
||||
const orig = originalState.get(obj.id);
|
||||
if (changesOnly && orig) {
|
||||
const origTransform = buildOrigTransform(orig);
|
||||
const same = Math.abs(orig.left - left) < 0.3 &&
|
||||
Math.abs(orig.top - top) < 0.3 &&
|
||||
Math.abs(orig.w - w) < 0.3 &&
|
||||
Math.abs(orig.h - h) < 0.3 &&
|
||||
(el.style.transform || '') === origTransform;
|
||||
if (same) return;
|
||||
}
|
||||
|
||||
items.push({
|
||||
nodeId: parseInt(obj.nodeId),
|
||||
type: obj.type,
|
||||
src: obj.src,
|
||||
left: left.toFixed(1) + 'mm',
|
||||
top: top.toFixed(1) + 'mm',
|
||||
w: w.toFixed(0) + 'mm',
|
||||
h: h.toFixed(0) + 'mm',
|
||||
rotate, flipH
|
||||
});
|
||||
});
|
||||
|
||||
// Collect changed nodes for this page
|
||||
const pageNodes = nodeEls.filter(n => n.pageNum === pageIndex + 1);
|
||||
const movedNodes = [];
|
||||
pageNodes.forEach(nd => {
|
||||
const el = nd.el;
|
||||
const left = parseFloat(el.style.left);
|
||||
const top = parseFloat(el.style.top);
|
||||
const orig = nodeOrigState.get(nd.nid);
|
||||
if (changesOnly && orig && Math.abs(orig.left - left) < 0.3 && Math.abs(orig.top - top) < 0.3) return;
|
||||
movedNodes.push({
|
||||
nodeId: parseInt(nd.nodeId),
|
||||
left: left.toFixed(1) + 'mm',
|
||||
top: top.toFixed(1) + 'mm'
|
||||
});
|
||||
});
|
||||
|
||||
if (items.length > 0 || movedNodes.length > 0) {
|
||||
const pageData = { page: pageIndex + 1 };
|
||||
if (items.length > 0) pageData.objects = items;
|
||||
if (movedNodes.length > 0) pageData.nodes = movedNodes;
|
||||
result.pages.push(pageData);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function copyConfig(changesOnly) {
|
||||
const config = buildConfig(changesOnly);
|
||||
const json = JSON.stringify(config, null, 2);
|
||||
navigator.clipboard.writeText(json).then(() => {
|
||||
showToast(changesOnly ? 'Changes copied!' : 'Full config copied!');
|
||||
}).catch(() => {
|
||||
console.log(json);
|
||||
showToast('Copied to console (clipboard blocked)');
|
||||
});
|
||||
}
|
||||
|
||||
function resetCurrentPage() {
|
||||
const pageNum = currentPage + 1;
|
||||
objects.filter(o => o.pageNum === pageNum).forEach(obj => {
|
||||
const orig = originalState.get(obj.id);
|
||||
if (!orig) return;
|
||||
obj.el.style.left = orig.left + 'mm';
|
||||
obj.el.style.top = orig.top + 'mm';
|
||||
obj.el.style.width = orig.w + 'mm';
|
||||
obj.el.style.height = orig.h + 'mm';
|
||||
obj.el.style.marginLeft = (-orig.w / 2) + 'mm';
|
||||
obj.el.style.marginTop = (-orig.h / 2) + 'mm';
|
||||
obj.el.style.transform = buildOrigTransform(orig);
|
||||
obj.el.classList.remove('obj-changed');
|
||||
|
||||
// Reset node and edges too
|
||||
moveNodeAndEdges(obj.el, orig.left, orig.top);
|
||||
});
|
||||
showToast(`Page ${pageNum} reset`);
|
||||
}
|
||||
|
||||
async function saveToServer() {
|
||||
const config = buildConfig(false);
|
||||
try {
|
||||
const resp = await fetch('/api/save-edits', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
taskType: 'space-route',
|
||||
docId: docId,
|
||||
data: config
|
||||
})
|
||||
});
|
||||
const result = await resp.json();
|
||||
if (result.ok) {
|
||||
showToast('Saved!');
|
||||
} else {
|
||||
showToast('Error: ' + result.error);
|
||||
}
|
||||
} catch (e) {
|
||||
showToast('Save failed: ' + e.message);
|
||||
}
|
||||
}
|
||||
|
||||
function showToast(msg) {
|
||||
const toast = document.getElementById('toast');
|
||||
toast.textContent = msg;
|
||||
toast.classList.add('show');
|
||||
setTimeout(() => toast.classList.remove('show'), 1500);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Apply editor JSON edits to space-route HTML.
|
||||
* Usage: node src/scripts/apply-route-edits.mjs output/html/space-route-edits.json
|
||||
*/
|
||||
import { readFileSync, writeFileSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const ROOT = join(__dirname, '..', '..');
|
||||
|
||||
const editsPath = process.argv[2] || join(ROOT, 'output', 'html', 'space-route-edits.json');
|
||||
const edits = JSON.parse(readFileSync(editsPath, 'utf-8'));
|
||||
const htmlPath = join(ROOT, 'output', 'html', edits.file);
|
||||
let html = readFileSync(htmlPath, 'utf-8');
|
||||
|
||||
// Split HTML into pages
|
||||
const pageRegex = /<div class="w-\[210mm\] h-\[297mm\][^>]*>/g;
|
||||
const pageStarts = [];
|
||||
let m;
|
||||
while ((m = pageRegex.exec(html)) !== null) {
|
||||
pageStarts.push(m.index);
|
||||
}
|
||||
pageStarts.push(html.length);
|
||||
|
||||
function getPageHtml(pageIndex) {
|
||||
return html.slice(pageStarts[pageIndex], pageStarts[pageIndex + 1]);
|
||||
}
|
||||
|
||||
function setPageHtml(pageIndex, newPageHtml) {
|
||||
html = html.slice(0, pageStarts[pageIndex]) + newPageHtml + html.slice(pageStarts[pageIndex + 1]);
|
||||
// Recalculate starts
|
||||
const diff = newPageHtml.length - (pageStarts[pageIndex + 1] - pageStarts[pageIndex]);
|
||||
for (let i = pageIndex + 1; i < pageStarts.length; i++) {
|
||||
pageStarts[i] += diff;
|
||||
}
|
||||
}
|
||||
|
||||
for (const pageEdit of edits.pages) {
|
||||
const pi = pageEdit.page - 1;
|
||||
let pageHtml = getPageHtml(pi);
|
||||
console.log(`Applying page ${pageEdit.page}...`);
|
||||
|
||||
// Apply object edits
|
||||
if (pageEdit.objects) {
|
||||
for (const obj of pageEdit.objects) {
|
||||
// Find the img with matching data-node-id and data-type on this page
|
||||
const nodeId = obj.nodeId;
|
||||
const type = obj.type;
|
||||
|
||||
// Build transform string
|
||||
let transform = '';
|
||||
if (obj.rotate) transform += `rotate(${obj.rotate}deg)`;
|
||||
if (obj.flipH) transform += ` scaleX(-1)`;
|
||||
transform = transform.trim();
|
||||
const transformAttr = transform ? `transform:${transform};` : '';
|
||||
|
||||
const w = parseFloat(obj.w);
|
||||
const h = parseFloat(obj.h);
|
||||
const left = parseFloat(obj.left);
|
||||
const top = parseFloat(obj.top);
|
||||
|
||||
// Match the img element by data-node-id and data-type
|
||||
const imgRegex = new RegExp(
|
||||
`(<img[^>]*data-node-id="${nodeId}"[^>]*data-type="${type}"[^>]*style=")([^"]*)(")`,
|
||||
'g'
|
||||
);
|
||||
|
||||
const newStyle = `left:${left.toFixed(1)}mm;top:${top.toFixed(1)}mm;width:${w}mm;height:${h}mm;margin-left:-${w/2}mm;margin-top:-${h/2}mm;z-index:4;${transformAttr}`;
|
||||
|
||||
const before = pageHtml;
|
||||
pageHtml = pageHtml.replace(imgRegex, `$1${newStyle}$3`);
|
||||
if (pageHtml === before) {
|
||||
// Try alternate order (data-type before data-node-id)
|
||||
const imgRegex2 = new RegExp(
|
||||
`(<img[^>]*data-type="${type}"[^>]*data-node-id="${nodeId}"[^>]*style=")([^"]*)(")`,
|
||||
'g'
|
||||
);
|
||||
pageHtml = pageHtml.replace(imgRegex2, `$1${newStyle}$3`);
|
||||
}
|
||||
console.log(` obj node:${nodeId} type:${type} → ${left.toFixed(1)},${top.toFixed(1)} ${w}×${h}mm${obj.rotate ? ' rot:'+obj.rotate+'°' : ''}${obj.flipH ? ' FLIP' : ''}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply node edits
|
||||
if (pageEdit.nodes) {
|
||||
for (const nd of pageEdit.nodes) {
|
||||
const nodeId = nd.nodeId;
|
||||
const left = parseFloat(nd.left);
|
||||
const top = parseFloat(nd.top);
|
||||
|
||||
// Update node div position
|
||||
const nodeRegex = new RegExp(
|
||||
`(<div[^>]*data-node-id="${nodeId}"[^>]*style=")(left:[^;]*;top:[^;]*)`,
|
||||
'g'
|
||||
);
|
||||
pageHtml = pageHtml.replace(nodeRegex, `$1left:${left.toFixed(1)}mm;top:${top.toFixed(1)}mm`);
|
||||
|
||||
// Update all edges connected to this node
|
||||
// Edge format: data-edge="A-B" where A or B matches nodeId
|
||||
// Update x1,y1 if nodeId is the first, x2,y2 if second
|
||||
const edgeRegex1 = new RegExp(
|
||||
`(<line data-edge="${nodeId}-\\d+"[^>]*)(x1="[^"]*")(\\s*)(y1="[^"]*")`,
|
||||
'g'
|
||||
);
|
||||
pageHtml = pageHtml.replace(edgeRegex1, `$1x1="${left.toFixed(1)}mm"$3y1="${top.toFixed(1)}mm"`);
|
||||
|
||||
const edgeRegex2 = new RegExp(
|
||||
`(<line data-edge="\\d+-${nodeId}"[^>]*)(x2="[^"]*")(\\s*)(y2="[^"]*")`,
|
||||
'g'
|
||||
);
|
||||
pageHtml = pageHtml.replace(edgeRegex2, `$1x2="${left.toFixed(1)}mm"$3y2="${top.toFixed(1)}mm"`);
|
||||
}
|
||||
console.log(` ${pageEdit.nodes.length} nodes updated`);
|
||||
}
|
||||
|
||||
setPageHtml(pi, pageHtml);
|
||||
}
|
||||
|
||||
writeFileSync(htmlPath, html, 'utf-8');
|
||||
console.log(`\nWritten to ${htmlPath}`);
|
||||
@@ -0,0 +1,742 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Generate static HTML for space-route worksheets.
|
||||
* Run: node src/scripts/generate-space-route.mjs
|
||||
* Output: output/html/space-route-1.html
|
||||
*/
|
||||
import { writeFileSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const ROOT = join(__dirname, '..', '..');
|
||||
|
||||
// ============================================================
|
||||
// CONFIGURATION PER PAGE
|
||||
// ============================================================
|
||||
// Asset path shortcuts
|
||||
const A = (n) => `../../assets/icons/pack3-asteroids/asteroid${n}.png`;
|
||||
const P = (n) => `../../assets/items/freighters/pod${n}.png`;
|
||||
const F = (n) => `../../assets/items/freighters/freighter${n}.png`;
|
||||
|
||||
const PAGES = [
|
||||
// Page 1: [3,8] — dest: asteroid
|
||||
{
|
||||
enemyShipImg: '../../assets/hero-images/spaceship4.jpeg',
|
||||
enemyLabel: 'Пиратский крейсер',
|
||||
playerShipImg: '../../assets/hero-images/spaceship2.png',
|
||||
footerImg: '../../assets/footers/planet3.jpeg',
|
||||
destObject: { img: A(5), w: 30, h: 30 },
|
||||
decoObjects: [
|
||||
{ img: A(3), w: 24, h: 24 }, { img: A(7), w: 24, h: 24 }, { img: A(11), w: 24, h: 24 },
|
||||
{ img: P(1), w: 28, h: 18 }, { img: P(2), w: 28, h: 18 },
|
||||
{ img: F(1), w: 38, h: 20 },
|
||||
],
|
||||
diffRange: [3, 8], routeLength: 8, seed: 42001,
|
||||
flipEnemy: false, flipPlayer: true,
|
||||
},
|
||||
// Page 2: [4,10] — dest: pod (radioactive)
|
||||
{
|
||||
enemyShipImg: '../../assets/hero-images/spaceship6.jpeg',
|
||||
enemyLabel: 'Патрульный разведчик',
|
||||
playerShipImg: '../../assets/hero-images/spaceship7.png',
|
||||
footerImg: '../../assets/footers/planet5.jpeg',
|
||||
destObject: { img: P(6), w: 30, h: 30 },
|
||||
decoObjects: [
|
||||
{ img: A(9), w: 24, h: 24 }, { img: A(14), w: 24, h: 24 }, { img: A(2), w: 24, h: 24 },
|
||||
{ img: P(4), w: 28, h: 18 }, { img: P(5), w: 28, h: 18 },
|
||||
{ img: F(2), w: 38, h: 20 },
|
||||
],
|
||||
diffRange: [4, 10], routeLength: 8, seed: 42002,
|
||||
flipEnemy: true, flipPlayer: true,
|
||||
},
|
||||
// Page 3: [2,18] — dest: freighter (stealth scout)
|
||||
{
|
||||
enemyShipImg: '../../assets/hero-images/spaceship3.jpeg',
|
||||
enemyLabel: 'Контрабандист',
|
||||
playerShipImg: '../../assets/hero-images/spaceship9.png',
|
||||
footerImg: '../../assets/footers/planet1.jpeg',
|
||||
destObject: { img: F(8), w: 38, h: 24 },
|
||||
decoObjects: [
|
||||
{ img: A(1), w: 24, h: 24 }, { img: A(10), w: 24, h: 24 }, { img: A(6), w: 24, h: 24 },
|
||||
{ img: P(8), w: 28, h: 18 }, { img: P(10), w: 28, h: 18 },
|
||||
{ img: F(5), w: 38, h: 20 },
|
||||
],
|
||||
diffRange: [2, 18], routeLength: 9, seed: 42003,
|
||||
flipEnemy: false, flipPlayer: true,
|
||||
},
|
||||
// Page 4: [6,12] — dest: pod (zoo biodome)
|
||||
{
|
||||
enemyShipImg: '../../assets/hero-images/spaceship1.jpeg',
|
||||
enemyLabel: 'Шахтёрский транспорт',
|
||||
playerShipImg: '../../assets/hero-images/spaceship8.png',
|
||||
footerImg: '../../assets/footers/planet7.jpeg',
|
||||
destObject: { img: P(16), w: 32, h: 28 },
|
||||
decoObjects: [
|
||||
{ img: A(12), w: 24, h: 24 }, { img: A(4), w: 24, h: 24 }, { img: A(15), w: 24, h: 24 },
|
||||
{ img: P(11), w: 28, h: 18 }, { img: P(13), w: 28, h: 18 },
|
||||
{ img: F(3), w: 38, h: 20 },
|
||||
],
|
||||
diffRange: [6, 12], routeLength: 8, seed: 42004,
|
||||
flipEnemy: true, flipPlayer: true,
|
||||
},
|
||||
// Page 5: [4,15] — dest: asteroid
|
||||
{
|
||||
enemyShipImg: '../../assets/hero-images/spaceship5.jpeg',
|
||||
enemyLabel: 'Корабль-призрак',
|
||||
playerShipImg: '../../assets/hero-images/spaceship3.png',
|
||||
footerImg: '../../assets/footers/planet2.jpeg',
|
||||
destObject: { img: A(16), w: 30, h: 30 },
|
||||
decoObjects: [
|
||||
{ img: A(8), w: 24, h: 24 }, { img: A(13), w: 24, h: 24 }, { img: A(3), w: 24, h: 24 },
|
||||
{ img: P(7), w: 28, h: 18 }, { img: P(9), w: 28, h: 18 },
|
||||
{ img: F(6), w: 38, h: 20 },
|
||||
],
|
||||
diffRange: [4, 15], routeLength: 8, seed: 42005,
|
||||
flipEnemy: true, flipPlayer: false,
|
||||
},
|
||||
// Page 6: [8,20] — HARD — dest: freighter (military)
|
||||
{
|
||||
enemyShipImg: '../../assets/hero-images/spaceship7.jpeg',
|
||||
enemyLabel: 'Военный фрегат',
|
||||
playerShipImg: '../../assets/hero-images/spaceship2.png',
|
||||
footerImg: '../../assets/footers/planet4.jpeg',
|
||||
destObject: { img: F(2), w: 38, h: 24 },
|
||||
decoObjects: [
|
||||
{ img: F(9), w: 38, h: 20 }, { img: F(10), w: 38, h: 20 },
|
||||
{ img: P(14), w: 28, h: 18 }, { img: P(15), w: 28, h: 18 }, { img: P(17), w: 28, h: 18 },
|
||||
{ img: A(3), w: 24, h: 24 }, { img: A(11), w: 24, h: 24 },
|
||||
],
|
||||
diffRange: [8, 20], routeLength: 9, seed: 42006,
|
||||
flipEnemy: true, flipPlayer: true,
|
||||
},
|
||||
// Page 7: [3,12] — dest: pod (comms relay)
|
||||
{
|
||||
enemyShipImg: '../../assets/hero-images/spaceship9.jpeg',
|
||||
enemyLabel: 'Торговый караван',
|
||||
playerShipImg: '../../assets/hero-images/spaceship8.png',
|
||||
footerImg: '../../assets/footers/planet6.jpeg',
|
||||
destObject: { img: P(18), w: 32, h: 28 },
|
||||
decoObjects: [
|
||||
{ img: A(7), w: 24, h: 24 }, { img: A(15), w: 24, h: 24 }, { img: A(5), w: 24, h: 24 },
|
||||
{ img: P(3), w: 28, h: 18 }, { img: P(12), w: 28, h: 18 },
|
||||
{ img: F(4), w: 38, h: 20 },
|
||||
],
|
||||
diffRange: [3, 12], routeLength: 8, seed: 42007,
|
||||
flipEnemy: true, flipPlayer: true,
|
||||
},
|
||||
// Page 8: [2,8] — dest: freighter (science)
|
||||
{
|
||||
enemyShipImg: '../../assets/hero-images/spaceship2.jpeg',
|
||||
enemyLabel: 'Исследователь',
|
||||
playerShipImg: '../../assets/hero-images/spaceship3.png',
|
||||
footerImg: '../../assets/footers/planet8.jpeg',
|
||||
destObject: { img: F(12), w: 38, h: 20 },
|
||||
decoObjects: [
|
||||
{ img: A(9), w: 24, h: 24 }, { img: A(8), w: 24, h: 24 }, { img: A(14), w: 24, h: 24 },
|
||||
{ img: P(1), w: 28, h: 18 }, { img: P(16), w: 28, h: 18 },
|
||||
{ img: F(7), w: 38, h: 20 },
|
||||
],
|
||||
diffRange: [2, 8], routeLength: 7, seed: 42008,
|
||||
flipEnemy: true, flipPlayer: false,
|
||||
},
|
||||
// Page 9: [10,30] — HARD — dest: pod (VIP)
|
||||
{
|
||||
enemyShipImg: '../../assets/hero-images/spaceship8.jpeg',
|
||||
enemyLabel: 'Рейдер',
|
||||
playerShipImg: '../../assets/hero-images/spaceship9.png',
|
||||
footerImg: '../../assets/footers/planet9.jpeg',
|
||||
destObject: { img: P(14), w: 32, h: 22 },
|
||||
decoObjects: [
|
||||
{ img: F(11), w: 38, h: 20 }, { img: F(5), w: 38, h: 20 },
|
||||
{ img: P(18), w: 28, h: 18 }, { img: P(6), w: 28, h: 18 }, { img: P(10), w: 28, h: 18 },
|
||||
{ img: A(16), w: 24, h: 24 }, { img: A(1), w: 24, h: 24 },
|
||||
],
|
||||
diffRange: [10, 30], routeLength: 9, seed: 42009,
|
||||
flipEnemy: true, flipPlayer: true,
|
||||
},
|
||||
];
|
||||
|
||||
const PLAYER_ROUTE_CELLS = 10;
|
||||
const GRID_COLS = 7;
|
||||
const GRID_ROWS = 9;
|
||||
const NODE_R_MM = 5;
|
||||
const MAP_TOP = 44;
|
||||
const MAP_BOTTOM = 242;
|
||||
const MAP_LEFT = 14;
|
||||
const MAP_RIGHT = 196;
|
||||
|
||||
// ============================================================
|
||||
// SEEDED PRNG
|
||||
// ============================================================
|
||||
let _seed = 0;
|
||||
function seedRng(s) { _seed = s | 0; }
|
||||
function seededRandom() {
|
||||
_seed |= 0; _seed = _seed + 0x6D2B79F5 | 0;
|
||||
let t = Math.imul(_seed ^ _seed >>> 15, 1 | _seed);
|
||||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||||
}
|
||||
function rand(min, max) {
|
||||
return Math.floor(seededRandom() * (max - min + 1)) + min;
|
||||
}
|
||||
function randF(min, max) {
|
||||
return min + seededRandom() * (max - min);
|
||||
}
|
||||
function distN(a, b) {
|
||||
return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// GRAPH
|
||||
// ============================================================
|
||||
function generateNodes() {
|
||||
const nodes = [];
|
||||
const cellW = (MAP_RIGHT - MAP_LEFT) / GRID_COLS;
|
||||
const cellH = (MAP_BOTTOM - MAP_TOP) / GRID_ROWS;
|
||||
const jitter = Math.min(cellW, cellH) * 0.25;
|
||||
let id = 0;
|
||||
for (let row = 0; row < GRID_ROWS; row++) {
|
||||
for (let col = 0; col < GRID_COLS; col++) {
|
||||
const hexOffset = (row % 2 === 1) ? cellW * 0.5 : 0;
|
||||
const baseX = MAP_LEFT + col * cellW + cellW / 2 + hexOffset;
|
||||
const baseY = MAP_TOP + row * cellH + cellH / 2;
|
||||
if (baseX < MAP_LEFT + 5 || baseX > MAP_RIGHT - 5) continue;
|
||||
const x = baseX + randF(-jitter, jitter);
|
||||
const y = baseY + randF(-jitter, jitter);
|
||||
const cx = Math.max(MAP_LEFT + NODE_R_MM, Math.min(MAP_RIGHT - NODE_R_MM, x));
|
||||
const cy = Math.max(MAP_TOP + NODE_R_MM, Math.min(MAP_BOTTOM - NODE_R_MM, y));
|
||||
nodes.push({ x: cx, y: cy, id: id++, value: 0, neighbors: [] });
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
function generateEdges(nodes) {
|
||||
const edges = [];
|
||||
const maxEdgeDist = 45;
|
||||
const candidates = [];
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
for (let j = i + 1; j < nodes.length; j++) {
|
||||
const d = distN(nodes[i], nodes[j]);
|
||||
if (d <= maxEdgeDist) candidates.push({ i, j, d });
|
||||
}
|
||||
}
|
||||
candidates.sort((a, b) => a.d - b.d);
|
||||
const MAX_DEGREE = 5;
|
||||
for (const { i, j } of candidates) {
|
||||
if (nodes[i].neighbors.length >= MAX_DEGREE || nodes[j].neighbors.length >= MAX_DEGREE) continue;
|
||||
let crosses = false;
|
||||
for (const e of edges) {
|
||||
if (e.i === i || e.j === i || e.i === j || e.j === j) continue;
|
||||
if (segmentsIntersect(nodes[i], nodes[j], nodes[e.i], nodes[e.j])) { crosses = true; break; }
|
||||
}
|
||||
if (!crosses) {
|
||||
edges.push({ i, j });
|
||||
nodes[i].neighbors.push(j);
|
||||
nodes[j].neighbors.push(i);
|
||||
}
|
||||
}
|
||||
ensureConnected(nodes, edges);
|
||||
for (const n of nodes) {
|
||||
if (n.neighbors.length < 2) {
|
||||
let best = null, bestDist = Infinity;
|
||||
for (const other of nodes) {
|
||||
if (other.id === n.id || n.neighbors.includes(other.id)) continue;
|
||||
const d = distN(n, other);
|
||||
if (d < bestDist) { bestDist = d; best = other; }
|
||||
}
|
||||
if (best) {
|
||||
edges.push({ i: n.id, j: best.id });
|
||||
n.neighbors.push(best.id);
|
||||
best.neighbors.push(n.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return edges;
|
||||
}
|
||||
|
||||
function trimNodeDegree(nodes, edges, nodeId, targetDegree) {
|
||||
const n = nodes[nodeId];
|
||||
while (n.neighbors.length > targetDegree) {
|
||||
let farthestNb = -1, farthestDist = 0;
|
||||
for (const nb of n.neighbors) {
|
||||
const d = distN(n, nodes[nb]);
|
||||
if (d > farthestDist) { farthestDist = d; farthestNb = nb; }
|
||||
}
|
||||
n.neighbors = n.neighbors.filter(nb => nb !== farthestNb);
|
||||
nodes[farthestNb].neighbors = nodes[farthestNb].neighbors.filter(nb => nb !== nodeId);
|
||||
for (let ei = edges.length - 1; ei >= 0; ei--) {
|
||||
const e = edges[ei];
|
||||
if ((e.i === nodeId && e.j === farthestNb) || (e.j === nodeId && e.i === farthestNb)) edges.splice(ei, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ensureConnected(nodes, edges) {
|
||||
const component = new Array(nodes.length).fill(-1);
|
||||
let compId = 0;
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
if (component[i] !== -1) continue;
|
||||
const queue = [i]; component[i] = compId;
|
||||
while (queue.length) {
|
||||
const cur = queue.shift();
|
||||
for (const nb of nodes[cur].neighbors) {
|
||||
if (component[nb] === -1) { component[nb] = compId; queue.push(nb); }
|
||||
}
|
||||
}
|
||||
compId++;
|
||||
}
|
||||
for (let c = 1; c < compId; c++) {
|
||||
let best = null, bestDist = Infinity;
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
if (component[i] !== 0) continue;
|
||||
for (let j = 0; j < nodes.length; j++) {
|
||||
if (component[j] !== c) continue;
|
||||
const d = distN(nodes[i], nodes[j]);
|
||||
if (d < bestDist) { bestDist = d; best = { i, j }; }
|
||||
}
|
||||
}
|
||||
if (best) {
|
||||
edges.push(best);
|
||||
nodes[best.i].neighbors.push(best.j);
|
||||
nodes[best.j].neighbors.push(best.i);
|
||||
for (let k = 0; k < nodes.length; k++) { if (component[k] === c) component[k] = 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function segmentsIntersect(p1, p2, p3, p4) {
|
||||
const d1 = crossP(p3, p4, p1), d2 = crossP(p3, p4, p2);
|
||||
const d3 = crossP(p1, p2, p3), d4 = crossP(p1, p2, p4);
|
||||
return ((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) && ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0));
|
||||
}
|
||||
function crossP(pi, pj, pk) {
|
||||
return (pk.x - pi.x) * (pj.y - pi.y) - (pj.x - pi.x) * (pk.y - pi.y);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// VALUES
|
||||
// ============================================================
|
||||
function assignValues(nodes, minVal, maxSpread) {
|
||||
const maxVal = minVal + Math.ceil(maxSpread * 1.3);
|
||||
const order = [...Array(nodes.length).keys()];
|
||||
order.sort((a, b) => nodes[b].neighbors.length - nodes[a].neighbors.length);
|
||||
for (let attempt = 0; attempt < 300; attempt++) {
|
||||
if (tryAssign(nodes, order, minVal, maxSpread, maxVal)) {
|
||||
if (validateGraph(nodes, minVal, maxSpread)) return true;
|
||||
}
|
||||
for (let i = order.length - 1; i > 0; i--) {
|
||||
if (seededRandom() < 0.4) { const j = rand(0, i); [order[i], order[j]] = [order[j], order[i]]; }
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function tryAssign(nodes, order, minVal, maxSpread, maxVal) {
|
||||
for (const n of nodes) n.value = -1;
|
||||
for (const idx of order) {
|
||||
const candidates = [];
|
||||
for (let v = minVal; v <= maxVal; v++) {
|
||||
let valid = true;
|
||||
const signedDiffs = [];
|
||||
for (const nb of nodes[idx].neighbors) {
|
||||
if (nodes[nb].value === -1) continue;
|
||||
const absDiff = Math.abs(v - nodes[nb].value);
|
||||
if (absDiff < 1 || absDiff > maxSpread) { valid = false; break; }
|
||||
const sd = v - nodes[nb].value;
|
||||
if (signedDiffs.includes(sd)) { valid = false; break; }
|
||||
signedDiffs.push(sd);
|
||||
}
|
||||
if (!valid) continue;
|
||||
for (const nb of nodes[idx].neighbors) {
|
||||
if (nodes[nb].value === -1) continue;
|
||||
const myDiff = v - nodes[nb].value;
|
||||
for (const nb2 of nodes[nb].neighbors) {
|
||||
if (nb2 === idx || nodes[nb2].value === -1) continue;
|
||||
if (nodes[nb2].value - nodes[nb].value === myDiff) { valid = false; break; }
|
||||
}
|
||||
if (!valid) break;
|
||||
}
|
||||
if (valid) candidates.push(v);
|
||||
}
|
||||
if (candidates.length === 0) return false;
|
||||
const center = minVal + maxSpread * 0.5;
|
||||
candidates.sort((a, b) => Math.abs(a - center) - Math.abs(b - center));
|
||||
const pick = Math.min(candidates.length - 1, Math.floor(seededRandom() * Math.min(candidates.length, 4)));
|
||||
nodes[idx].value = candidates[pick];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function validateGraph(nodes, minVal, maxSpread) {
|
||||
for (const n of nodes) {
|
||||
if (n.value < minVal) return false;
|
||||
const diffs = [];
|
||||
for (const nb of n.neighbors) {
|
||||
const d = nodes[nb].value - n.value;
|
||||
if (Math.abs(d) < 1 || Math.abs(d) > maxSpread) return false;
|
||||
if (diffs.includes(d)) return false;
|
||||
diffs.push(d);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// ROUTES
|
||||
// ============================================================
|
||||
function findCornerNode(nodes, corner) {
|
||||
let sorted;
|
||||
if (corner === 'top-left') sorted = [...nodes].sort((a, b) => (a.x + a.y * 2) - (b.x + b.y * 2));
|
||||
else sorted = [...nodes].sort((a, b) => (a.x - a.y * 2) - (b.x - b.y * 2));
|
||||
return sorted[0];
|
||||
}
|
||||
|
||||
function findDirectionalRoute(nodes, startId, length, targetArea) {
|
||||
const best = { path: null, score: -Infinity };
|
||||
for (let trial = 0; trial < 30; trial++) {
|
||||
const path = [startId];
|
||||
if (buildDirectionalPath(nodes, path, length, targetArea)) {
|
||||
const score = routeQualityScore(nodes, path, targetArea);
|
||||
if (score > best.score) { best.path = [...path]; best.score = score; }
|
||||
}
|
||||
}
|
||||
return best.path;
|
||||
}
|
||||
|
||||
// Route uses a waypoint system: go toward waypoint first, then toward final target.
|
||||
// This creates natural direction changes without looping.
|
||||
function buildDirectionalPath(nodes, path, targetLen, target) {
|
||||
// Pick a waypoint roughly halfway through the route — offset from straight line
|
||||
const start = nodes[path[0]];
|
||||
const midX = (start.x + target.x) / 2;
|
||||
const midY = (start.y + target.y) / 2;
|
||||
// Offset waypoint perpendicular to the start→target line
|
||||
const dx = target.x - start.x;
|
||||
const dy = target.y - start.y;
|
||||
const perpX = -dy * 0.4 * (seededRandom() > 0.5 ? 1 : -1);
|
||||
const perpY = dx * 0.4 * (seededRandom() > 0.5 ? 1 : -1);
|
||||
const waypoint = {
|
||||
x: Math.max(MAP_LEFT + 20, Math.min(MAP_RIGHT - 20, midX + perpX)),
|
||||
y: Math.max(MAP_TOP + 20, Math.min(MAP_BOTTOM - 20, midY + perpY))
|
||||
};
|
||||
return buildPathWithWaypoint(nodes, path, targetLen, waypoint, target);
|
||||
}
|
||||
|
||||
function buildPathWithWaypoint(nodes, path, targetLen, waypoint, finalTarget) {
|
||||
if (path.length === targetLen + 1) return true;
|
||||
const current = nodes[path[path.length - 1]];
|
||||
const nbs = [...current.neighbors].filter(nb => !path.includes(nb));
|
||||
if (nbs.length === 0) return false;
|
||||
|
||||
// First ~40% of route: head toward waypoint. Rest: head toward final target.
|
||||
const progress = path.length / (targetLen + 1);
|
||||
const activeTarget = progress < 0.4 ? waypoint : finalTarget;
|
||||
|
||||
const scored = nbs.map(nb => {
|
||||
const n = nodes[nb];
|
||||
const distToTarget = Math.sqrt((n.x - activeTarget.x) ** 2 + (n.y - activeTarget.y) ** 2);
|
||||
const curDist = Math.sqrt((current.x - activeTarget.x) ** 2 + (current.y - activeTarget.y) ** 2);
|
||||
const stepsLeft = targetLen - path.length;
|
||||
const randomFactor = stepsLeft <= 2 ? randF(-25, 25) : randF(-10, 10);
|
||||
return { nb, score: (curDist - distToTarget) + randomFactor };
|
||||
});
|
||||
scored.sort((a, b) => b.score - a.score);
|
||||
for (const { nb } of scored) {
|
||||
path.push(nb);
|
||||
if (buildPathWithWaypoint(nodes, path, targetLen, waypoint, finalTarget)) return true;
|
||||
path.pop();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function routeQualityScore(nodes, path, target) {
|
||||
const start = nodes[path[0]], end = nodes[path[path.length - 1]];
|
||||
const endDist = Math.sqrt((end.x - target.x) ** 2 + (end.y - target.y) ** 2);
|
||||
// Prefer routes that cover more area (spread out)
|
||||
let totalDist = 0;
|
||||
for (let i = 1; i < path.length; i++) totalDist += distN(nodes[path[i - 1]], nodes[path[i]]);
|
||||
const straightLine = distN(start, end);
|
||||
// Reward: close to target, long travel distance (not straight), reasonable spread
|
||||
return -endDist * 0.5 + totalDist * 0.1 + straightLine * 0.2;
|
||||
}
|
||||
|
||||
function findShortestPath(nodes, fromId, toId) {
|
||||
const prev = new Array(nodes.length).fill(-1);
|
||||
const visited = new Set([fromId]);
|
||||
const queue = [fromId];
|
||||
while (queue.length) {
|
||||
const cur = queue.shift();
|
||||
if (cur === toId) break;
|
||||
for (const nb of nodes[cur].neighbors) {
|
||||
if (!visited.has(nb)) { visited.add(nb); prev[nb] = cur; queue.push(nb); }
|
||||
}
|
||||
}
|
||||
if (!visited.has(toId)) return null;
|
||||
const path = []; let cur = toId;
|
||||
while (cur !== -1) { path.unshift(cur); cur = prev[cur]; }
|
||||
return path;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// PAGE GENERATION
|
||||
// ============================================================
|
||||
function generatePage(config, pageIndex) {
|
||||
seedRng(config.seed);
|
||||
let nodes, edges, enemyRoute, playerRoute;
|
||||
let success = false;
|
||||
for (let attempt = 0; attempt < 80; attempt++) {
|
||||
nodes = generateNodes();
|
||||
edges = generateEdges(nodes);
|
||||
const enemyStartNode = findCornerNode(nodes, 'top-left');
|
||||
const playerStartNode = findCornerNode(nodes, 'bottom-left');
|
||||
trimNodeDegree(nodes, edges, enemyStartNode.id, 2);
|
||||
trimNodeDegree(nodes, edges, playerStartNode.id, 2);
|
||||
const [minVal, maxSpread] = config.diffRange;
|
||||
if (!assignValues(nodes, minVal, maxSpread)) continue;
|
||||
const targetArea = { x: MAP_RIGHT - 30, y: MAP_BOTTOM - 40 };
|
||||
enemyRoute = findDirectionalRoute(nodes, enemyStartNode.id, config.routeLength, targetArea);
|
||||
if (!enemyRoute) continue;
|
||||
const dest = enemyRoute[enemyRoute.length - 1];
|
||||
if (playerStartNode.id === dest || enemyRoute.includes(playerStartNode.id)) continue;
|
||||
playerRoute = findShortestPath(nodes, playerStartNode.id, dest);
|
||||
if (playerRoute && playerRoute.length >= 3) { success = true; break; }
|
||||
}
|
||||
if (!success) return `<div class="w-[210mm] h-[297mm] mx-auto bg-white flex items-center justify-center text-red-500 text-xl">Page ${pageIndex + 1}: Generation failed</div>`;
|
||||
|
||||
// ---- ROUTE VALIDATION ----
|
||||
const [minVal, maxSpread] = config.diffRange;
|
||||
console.log(` Page ${pageIndex + 1} validation:`);
|
||||
|
||||
// Validate enemy route
|
||||
console.log(` Enemy route (${enemyRoute.length} nodes): ${enemyRoute.map(id => `[${id}]=${nodes[id].value}`).join(' → ')}`);
|
||||
const enemyDiffs = [];
|
||||
let enemyValid = true;
|
||||
for (let i = 0; i < enemyRoute.length - 1; i++) {
|
||||
const from = enemyRoute[i], to = enemyRoute[i + 1];
|
||||
const isNeighbor = nodes[from].neighbors.includes(to);
|
||||
const diff = nodes[to].value - nodes[from].value;
|
||||
enemyDiffs.push(diff);
|
||||
if (!isNeighbor) {
|
||||
console.log(` ❌ EDGE MISSING: node ${from}(${nodes[from].value}) → ${to}(${nodes[to].value}) are NOT neighbors!`);
|
||||
enemyValid = false;
|
||||
}
|
||||
}
|
||||
console.log(` Enemy diffs: ${enemyDiffs.map(d => (d > 0 ? '+' : '') + d).join(', ')}`);
|
||||
// Check uniqueness at each step
|
||||
for (let i = 0; i < enemyRoute.length - 1; i++) {
|
||||
const from = enemyRoute[i];
|
||||
const diff = enemyDiffs[i];
|
||||
// Check no other neighbor of 'from' has the same diff
|
||||
const conflicting = nodes[from].neighbors.filter(nb => nb !== enemyRoute[i + 1] && (nodes[nb].value - nodes[from].value) === diff);
|
||||
if (conflicting.length > 0) {
|
||||
console.log(` ❌ AMBIGUITY at node ${from}(${nodes[from].value}): diff ${diff > 0 ? '+' : ''}${diff} also leads to node(s) ${conflicting.map(c => `${c}(${nodes[c].value})`).join(', ')}`);
|
||||
enemyValid = false;
|
||||
}
|
||||
}
|
||||
if (enemyValid) console.log(` ✅ Enemy route valid`);
|
||||
|
||||
// Validate player route
|
||||
console.log(` Player route (${playerRoute.length} nodes): ${playerRoute.map(id => `[${id}]=${nodes[id].value}`).join(' → ')}`);
|
||||
let playerValid = true;
|
||||
for (let i = 0; i < playerRoute.length - 1; i++) {
|
||||
const from = playerRoute[i], to = playerRoute[i + 1];
|
||||
if (!nodes[from].neighbors.includes(to)) {
|
||||
console.log(` ❌ EDGE MISSING: node ${from}(${nodes[from].value}) → ${to}(${nodes[to].value}) are NOT neighbors!`);
|
||||
playerValid = false;
|
||||
}
|
||||
}
|
||||
// Check player reaches same destination as enemy
|
||||
const playerDest = playerRoute[playerRoute.length - 1];
|
||||
const enemyDest = enemyRoute[enemyRoute.length - 1];
|
||||
if (playerDest !== enemyDest) {
|
||||
console.log(` ❌ DESTINATION MISMATCH: player ends at ${playerDest}(${nodes[playerDest].value}), enemy ends at ${enemyDest}(${nodes[enemyDest].value})`);
|
||||
playerValid = false;
|
||||
} else {
|
||||
console.log(` ✅ Player reaches enemy destination: node ${enemyDest}(${nodes[enemyDest].value})`);
|
||||
}
|
||||
if (playerValid) console.log(` ✅ Player route valid`);
|
||||
|
||||
return renderPage(nodes, edges, enemyRoute, playerRoute, config, pageIndex);
|
||||
}
|
||||
|
||||
function renderPage(nodes, edges, enemyRoute, playerRoute, config, pageIndex) {
|
||||
const dest = enemyRoute[enemyRoute.length - 1];
|
||||
const enemyStart = enemyRoute[0];
|
||||
const playerStart = playerRoute[0];
|
||||
|
||||
const decoNodeIds = [];
|
||||
// Exclude all route nodes + neighbors of start nodes (no asteroids near starting points)
|
||||
const usedIds = new Set([enemyStart, playerStart, dest, ...enemyRoute, ...playerRoute,
|
||||
...nodes[enemyStart].neighbors, ...nodes[playerStart].neighbors]);
|
||||
const availableNodes = nodes.filter(n => !usedIds.has(n.id));
|
||||
const sortedByRegion = [...availableNodes].sort((a, b) => a.y - b.y);
|
||||
const regionSize = Math.floor(sortedByRegion.length / (config.decoObjects.length + 1));
|
||||
for (let di = 0; di < config.decoObjects.length; di++) {
|
||||
const regionStart = regionSize * (di + 0.5);
|
||||
const idx = Math.min(Math.floor(regionStart + randF(-2, 2)), sortedByRegion.length - 1);
|
||||
if (idx >= 0 && !decoNodeIds.includes(sortedByRegion[idx].id)) decoNodeIds.push(sortedByRegion[Math.max(0, idx)].id);
|
||||
}
|
||||
|
||||
let edgeSvg = '';
|
||||
for (const e of edges) {
|
||||
const n1 = nodes[e.i], n2 = nodes[e.j];
|
||||
edgeSvg += `<line data-edge="${e.i}-${e.j}" x1="${n1.x.toFixed(1)}mm" y1="${n1.y.toFixed(1)}mm" x2="${n2.x.toFixed(1)}mm" y2="${n2.y.toFixed(1)}mm" stroke="#a5b4fc" stroke-width="0.7" stroke-dasharray="2.5 2" stroke-linecap="round" opacity="0.45"/>`;
|
||||
}
|
||||
|
||||
const asteroidNodeIds = new Set([dest, ...decoNodeIds]);
|
||||
let nodesHtml = '';
|
||||
for (const n of nodes) {
|
||||
const isEnemyStart = n.id === enemyStart;
|
||||
const isPlayerStart = n.id === playerStart;
|
||||
const isStartNode = isEnemyStart || isPlayerStart;
|
||||
const hasAsteroid = asteroidNodeIds.has(n.id);
|
||||
const borderWidth = isStartNode ? '2.5px' : '1.5px';
|
||||
const borderColor = isEnemyStart ? 'border-red-400' : isPlayerStart ? 'border-sky-400' : 'border-indigo-300';
|
||||
const bgColor = isEnemyStart ? 'bg-red-50' : isPlayerStart ? 'bg-sky-50' : 'bg-white';
|
||||
const fontSize = isStartNode ? '13px' : '11px';
|
||||
const shadow = isEnemyStart ? 'shadow-md shadow-red-200' : isPlayerStart ? 'shadow-md shadow-sky-200' : 'shadow-sm';
|
||||
const baseSize = isStartNode ? NODE_R_MM * 2.4 : NODE_R_MM * 2;
|
||||
const size = hasAsteroid ? baseSize / 1.5 : baseSize;
|
||||
const offset = size / 2;
|
||||
nodesHtml += `\n <div class="absolute flex items-center justify-center rounded-full ${borderColor} ${bgColor} ${shadow}" data-node-id="${n.id}" data-neighbors="${n.neighbors.join(',')}" style="left:${n.x.toFixed(1)}mm;top:${n.y.toFixed(1)}mm;width:${size.toFixed(1)}mm;height:${size.toFixed(1)}mm;margin-left:-${offset.toFixed(1)}mm;margin-top:-${offset.toFixed(1)}mm;z-index:15;border-width:${borderWidth};"><span class="font-extrabold text-indigo-950 leading-none" style="font-size:${fontSize};">${n.value}</span></div>`;
|
||||
}
|
||||
|
||||
const destNode = nodes[dest];
|
||||
const dw = config.destObject.w, dh = config.destObject.h;
|
||||
const destObjHtml = `\n <img src="${config.destObject.img}" class="absolute object-contain space-obj" data-node-id="${dest}" data-type="dest" style="left:${destNode.x.toFixed(1)}mm;top:${destNode.y.toFixed(1)}mm;width:${dw}mm;height:${dh}mm;margin-left:-${dw/2}mm;margin-top:-${dh/2}mm;z-index:4;" alt="">`;
|
||||
|
||||
let decosHtml = '';
|
||||
for (let di = 0; di < config.decoObjects.length && di < decoNodeIds.length; di++) {
|
||||
const dn = nodes[decoNodeIds[di]];
|
||||
const ow = config.decoObjects[di].w, oh = config.decoObjects[di].h;
|
||||
decosHtml += `\n <img src="${config.decoObjects[di].img}" class="absolute object-contain space-obj" data-node-id="${decoNodeIds[di]}" data-type="deco" style="left:${dn.x.toFixed(1)}mm;top:${dn.y.toFixed(1)}mm;width:${ow}mm;height:${oh}mm;margin-left:-${ow/2}mm;margin-top:-${oh/2}mm;z-index:4;" alt="">`;
|
||||
}
|
||||
|
||||
let starsHtml = '';
|
||||
for (let i = 0; i < 70; i++) {
|
||||
const sx = randF(6, 204).toFixed(1);
|
||||
const sy = randF(30, 270).toFixed(1);
|
||||
const size = randF(10, 22).toFixed(0);
|
||||
const opacity = randF(0.12, 0.35).toFixed(2);
|
||||
const symbols = ['✦', '✧', '⋆', '·', '∗', '⊹'];
|
||||
starsHtml += `<span class="absolute text-indigo-300" style="left:${sx}mm;top:${sy}mm;font-size:${size}px;opacity:${opacity};z-index:2;pointer-events:none;">${symbols[rand(0, symbols.length - 1)]}</span>`;
|
||||
}
|
||||
|
||||
const enemyDiffs = [];
|
||||
for (let i = 1; i < enemyRoute.length; i++) enemyDiffs.push(nodes[enemyRoute[i]].value - nodes[enemyRoute[i - 1]].value);
|
||||
|
||||
let enemyRouteCells = `<div class="inline-flex items-center justify-center rounded-full border-[2px] border-red-400 bg-red-50 shrink-0" style="width:8mm;height:8mm;"><span class="text-[12px] font-extrabold text-indigo-950">${nodes[enemyStart].value}</span></div>`;
|
||||
for (const diff of enemyDiffs) {
|
||||
const diffStr = (diff > 0 ? '+' : '') + diff;
|
||||
enemyRouteCells += `<div class="inline-flex items-center justify-center shrink-0 border-[1.5px] border-indigo-300 rounded bg-white" style="width:9mm;height:7mm;margin-left:1mm;"><span class="text-[11px] font-bold text-indigo-950">${diffStr}</span></div>`;
|
||||
}
|
||||
|
||||
const cellCount = Math.max(PLAYER_ROUTE_CELLS, playerRoute.length - 1);
|
||||
let playerRouteCells = `<div class="inline-flex items-center justify-center rounded-full border-[2px] border-sky-400 bg-sky-50 shrink-0" style="width:8mm;height:8mm;"><span class="text-[12px] font-extrabold text-indigo-950">${nodes[playerStart].value}</span></div>`;
|
||||
for (let i = 0; i < cellCount; i++) {
|
||||
playerRouteCells += `<div class="inline-flex items-center justify-center shrink-0 border-[1.5px] border-indigo-200 border-dashed rounded bg-white" style="width:9mm;height:7mm;margin-left:1mm;"></div>`;
|
||||
}
|
||||
|
||||
const isLastPage = pageIndex === PAGES.length - 1;
|
||||
const pageBreak = isLastPage ? '' : 'break-after: page;';
|
||||
const [minVal, maxSpread] = config.diffRange;
|
||||
const nodeValues = nodes.map(n => n.value);
|
||||
const actualMin = Math.min(...nodeValues);
|
||||
const actualMax = Math.max(...nodeValues);
|
||||
|
||||
return `
|
||||
<div class="w-[210mm] h-[297mm] relative overflow-hidden mx-auto bg-white" data-enemy-route="${enemyRoute.join(',')}" data-player-route="${playerRoute.join(',')}" style="${pageBreak}">
|
||||
<div class="absolute bottom-0 left-0 right-0 h-[80mm] z-0">
|
||||
<div class="absolute top-0 left-0 right-0 h-full z-10" style="background: linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%);"></div>
|
||||
<img src="${config.footerImg}" class="w-full h-full object-cover object-top" alt="">
|
||||
</div>
|
||||
<div class="absolute inset-0" style="z-index:3;">
|
||||
${starsHtml}
|
||||
${destObjHtml}
|
||||
${decosHtml}
|
||||
<svg class="absolute inset-0 w-full h-full" style="z-index:5;" xmlns="http://www.w3.org/2000/svg">
|
||||
${edgeSvg}
|
||||
</svg>
|
||||
${nodesHtml}
|
||||
|
||||
<!-- Header with enemy ship (under nodes and edges) -->
|
||||
<div class="absolute top-0 left-0 right-0" style="z-index:3;">
|
||||
<div class="flex items-start">
|
||||
<img src="${config.enemyShipImg}" class="shrink-0 object-contain" style="width:48%;max-height:50mm;${config.flipEnemy ? 'transform:scaleX(-1);' : ''}" alt="">
|
||||
<div class="flex-1 flex flex-col items-center justify-center text-center pt-[5mm]">
|
||||
<h1 class="text-[1.4rem] font-extrabold leading-tight tracking-tight text-indigo-950">Проложи Маршрут</h1>
|
||||
<p class="text-[0.75rem] font-medium text-indigo-300 mt-0">Найди путь в космосе!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Enemy route card -->
|
||||
<div class="absolute z-30" style="top:19mm;right:8mm;">
|
||||
<div class="flex items-center gap-[2mm] px-[3mm] py-[1.5mm] rounded-lg border-[1.5px] border-indigo-100" style="background:rgba(255,255,255,0.75);">
|
||||
<div class="text-[11px] font-bold text-indigo-900 whitespace-nowrap">${config.enemyLabel}:</div>
|
||||
<div class="flex items-center flex-nowrap">${enemyRouteCells}</div>
|
||||
</div>
|
||||
<div class="text-[10px] text-indigo-400 mt-[0.5mm] text-right pr-[2mm]">📍 Проследи маршрут — куда он летит?</div>
|
||||
</div>
|
||||
|
||||
<!-- Player ship -->
|
||||
<img src="${config.playerShipImg}" class="absolute object-contain" style="bottom:8mm;left:0;width:48%;max-height:60mm;z-index:4;${config.flipPlayer ? 'transform:scaleX(-1);' : ''}" alt="">
|
||||
|
||||
<!-- Player route card -->
|
||||
<div class="absolute z-30" style="bottom:5mm;right:8mm;">
|
||||
<div class="text-[12px] font-semibold text-gray-800 mb-[1mm] text-right pr-[2mm]">Рассчитай маршрут до цели перехвата</div>
|
||||
<div class="flex items-center gap-[2mm] px-[3mm] py-[1.5mm] rounded-lg border-[1.5px] border-indigo-100" style="background:rgba(255,255,255,0.75);">
|
||||
<div class="text-[11px] font-bold text-indigo-900 whitespace-nowrap">Твой истребитель:</div>
|
||||
<div class="flex items-center flex-nowrap">${playerRouteCells}</div>
|
||||
</div>
|
||||
<div class="text-[12px] font-semibold text-gray-800 mt-[1mm] text-right pr-[2mm]">✏️ Запиши разницу чисел, чтобы добраться до цели!</div>
|
||||
</div>
|
||||
|
||||
<!-- Debug -->
|
||||
<div class="absolute z-40 text-[7px] text-indigo-300" style="bottom:3mm;left:3mm;">
|
||||
[${minVal},${maxSpread}] | ${nodes.length} nodes | values ${actualMin}-${actualMax} | enemy ${enemyRoute.length} steps | player shortest ${playerRoute.length - 1} steps
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// MAIN
|
||||
// ============================================================
|
||||
let pagesHtml = '';
|
||||
for (let i = 0; i < PAGES.length; i++) {
|
||||
console.log(`Generating page ${i + 1}...`);
|
||||
pagesHtml += generatePage(PAGES[i], i);
|
||||
}
|
||||
|
||||
const fullHtml = `<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<title>Проложи Маршрут</title>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: { extend: { fontFamily: { nunito: ['Nunito', 'sans-serif'] } } }
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@page { size: A4; margin: 0; }
|
||||
body { font-family: 'Nunito', sans-serif; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-200 font-nunito">
|
||||
${pagesHtml}
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
const outPath = join(ROOT, 'output', 'html', 'space-route-1.html');
|
||||
writeFileSync(outPath, fullHtml, 'utf-8');
|
||||
console.log(`Written to ${outPath}`);
|
||||
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Generate output HTML from template + data for space-route documents.
|
||||
*
|
||||
* Usage: node generate.mjs <docId>
|
||||
* Example: node generate.mjs space-route-1
|
||||
*
|
||||
* Reads: docs/<docId>.template.html
|
||||
* Reads: docs/<docId>.data.json (optional)
|
||||
* Writes: docs/<docId>.output.html
|
||||
*
|
||||
* data.json format (from space-route editor):
|
||||
* {
|
||||
* pages: [{
|
||||
* page: 1,
|
||||
* objects: [{ nodeId, type, src, left, top, w, h, rotate, flipH }],
|
||||
* nodes: [{ nodeId, left, top }]
|
||||
* }]
|
||||
* }
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
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 <docId>');
|
||||
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'));
|
||||
html = applyData(html, data);
|
||||
console.log(`Applied data from ${data.pages?.length || 0} pages`);
|
||||
}
|
||||
|
||||
writeFileSync(outputPath, html);
|
||||
console.log(`Generated: ${outputPath}`);
|
||||
|
||||
function applyData(html, data) {
|
||||
if (!data.pages) return html;
|
||||
|
||||
// Split by page divs
|
||||
const pageRegex = /<div class="w-\[210mm\] h-\[297mm\]"/g;
|
||||
const starts = [];
|
||||
let match;
|
||||
while ((match = pageRegex.exec(html)) !== null) {
|
||||
starts.push(match.index);
|
||||
}
|
||||
|
||||
if (starts.length === 0) return html;
|
||||
|
||||
for (let i = data.pages.length - 1; i >= 0; i--) {
|
||||
const pageData = data.pages[i];
|
||||
const pageNum = pageData.page || (i + 1);
|
||||
const pageIdx = pageNum - 1;
|
||||
|
||||
if (pageIdx >= starts.length) continue;
|
||||
|
||||
const pageStart = starts[pageIdx];
|
||||
const pageEnd = pageIdx + 1 < starts.length ? starts[pageIdx + 1] : html.length;
|
||||
let pageHtml = html.slice(pageStart, pageEnd);
|
||||
|
||||
// Apply object positions
|
||||
if (pageData.objects) {
|
||||
for (const obj of pageData.objects) {
|
||||
pageHtml = applyObject(pageHtml, obj);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply node positions and update edges
|
||||
if (pageData.nodes) {
|
||||
for (const node of pageData.nodes) {
|
||||
pageHtml = applyNode(pageHtml, node);
|
||||
}
|
||||
}
|
||||
|
||||
html = html.slice(0, pageStart) + pageHtml + html.slice(pageEnd);
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function applyObject(pageHtml, obj) {
|
||||
// Match: <img class="space-obj" data-node-id="N" data-type="..." style="..."
|
||||
const nodeId = obj.nodeId;
|
||||
const regex = new RegExp(
|
||||
`(<img class="space-obj"[^>]*data-node-id="${nodeId}"[^>]*style=")([^"]*)(")`
|
||||
);
|
||||
|
||||
return pageHtml.replace(regex, (match, prefix, oldStyle, suffix) => {
|
||||
const parts = [];
|
||||
parts.push(`left: ${obj.left}`);
|
||||
parts.push(`top: ${obj.top}`);
|
||||
if (obj.w) parts.push(`width: ${obj.w}`);
|
||||
if (obj.h) parts.push(`height: ${obj.h}`);
|
||||
|
||||
const transforms = [];
|
||||
if (obj.rotate) transforms.push(`rotate(${obj.rotate}deg)`);
|
||||
if (obj.flipH) transforms.push('scaleX(-1)');
|
||||
if (transforms.length) parts.push(`transform: ${transforms.join(' ')}`);
|
||||
|
||||
// Preserve margin if present in old style
|
||||
const marginMatch = oldStyle.match(/margin[^;]+;/);
|
||||
if (marginMatch) parts.push(marginMatch[0].replace(/;$/, ''));
|
||||
|
||||
return prefix + parts.join('; ') + ';' + suffix;
|
||||
});
|
||||
}
|
||||
|
||||
function applyNode(pageHtml, node) {
|
||||
// Update node div position
|
||||
const nodeRegex = new RegExp(
|
||||
`(<div[^>]*data-node-id="${node.nodeId}"[^>]*style=")([^"]*)(")`
|
||||
);
|
||||
|
||||
pageHtml = pageHtml.replace(nodeRegex, (match, prefix, oldStyle, suffix) => {
|
||||
const newStyle = oldStyle
|
||||
.replace(/left:\s*[^;]+/, `left: ${node.left}`)
|
||||
.replace(/top:\s*[^;]+/, `top: ${node.top}`);
|
||||
return prefix + newStyle + suffix;
|
||||
});
|
||||
|
||||
// Update edges connected to this node
|
||||
const leftMm = parseFloat(node.left);
|
||||
const topMm = parseFloat(node.top);
|
||||
|
||||
// Edges where this node is first: <line data-edge="N-M" x1="..." y1="..."
|
||||
const edgeRegex1 = new RegExp(
|
||||
`(<line[^>]*data-edge="${node.nodeId}-\\d+"[^>]*)(x1=")[^"]*("\\s*y1=")[^"]*(")`,'g'
|
||||
);
|
||||
pageHtml = pageHtml.replace(edgeRegex1, (match, prefix, x1p, y1p, suffix) => {
|
||||
return `${prefix}${x1p}${leftMm}mm${y1p}${topMm}mm${suffix}`;
|
||||
});
|
||||
|
||||
// Edges where this node is second: <line data-edge="M-N" ... x2="..." y2="..."
|
||||
const edgeRegex2 = new RegExp(
|
||||
`(<line[^>]*data-edge="\\d+-${node.nodeId}"[^>]*)(x2=")[^"]*("\\s*y2=")[^"]*(")`,'g'
|
||||
);
|
||||
pageHtml = pageHtml.replace(edgeRegex2, (match, prefix, x2p, y2p, suffix) => {
|
||||
return `${prefix}${x2p}${leftMm}mm${y2p}${topMm}mm${suffix}`;
|
||||
});
|
||||
|
||||
return pageHtml;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
{
|
||||
"id": "space-worksheet2",
|
||||
"title": "Исследуй Планету",
|
||||
"description": "3-page space worksheet: addition A+B±C (result 0-40), multiply by 5 variants, compound A×B+C×D",
|
||||
"labels": {
|
||||
"title": "Исследуй Планету",
|
||||
"subtitle": "Собери ресурсы, решая примеры!",
|
||||
"footerBubble": "Итого собрано на планете:"
|
||||
},
|
||||
"theme": {
|
||||
"style": "space",
|
||||
"template": "space-base",
|
||||
"icons": "assets/icons/pack2/"
|
||||
},
|
||||
"layout": {
|
||||
"columns": 2,
|
||||
"problemsPerPage": 20
|
||||
},
|
||||
"pages": [
|
||||
{
|
||||
"task": "A + B + C, где A от 12 до 24, B ±(от 6 до 10), C ±(от 2 до 5). Результат от 0 до 40 включительно",
|
||||
"problemCount": 20,
|
||||
"heroImage": "assets/hero-images/spaceship1.jpeg",
|
||||
"footerImage": "assets/footers/planet2.jpeg",
|
||||
"heroDirection": "row-reverse"
|
||||
},
|
||||
{
|
||||
"task": "5 + 5 + 5 (сложение пятерок: 2, 3 или 4 штуки) ИЛИ 5 × N (N от 1 до 12) ИЛИ 5 × N ± 5",
|
||||
"problemCount": 20,
|
||||
"heroImage": "assets/hero-images/spaceship3.png",
|
||||
"footerImage": "assets/footers/planet4.jpeg",
|
||||
"heroDirection": "row"
|
||||
},
|
||||
{
|
||||
"task": "A × B + C × D, где A от 2 до 4, B от 1 до 3, C от 2 до 3, D от 1 до 2",
|
||||
"problemCount": 20,
|
||||
"heroImage": "assets/hero-images/spaceship5.jpeg",
|
||||
"footerImage": "assets/footers/planet6.jpeg",
|
||||
"heroDirection": "row-reverse"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
{
|
||||
"id": "space-worksheet3",
|
||||
"title": "Исследуй Планету",
|
||||
"description": "9-page space worksheet combining patterns from worksheet1 and worksheet2: addition, multiply by 5, multiplication table, constrained addition, mixed fives, compound multiplication",
|
||||
"labels": {
|
||||
"title": "Исследуй Планету",
|
||||
"subtitle": "Собери ресурсы, решая примеры!",
|
||||
"footerBubble": "Итого собрано на планете:"
|
||||
},
|
||||
"theme": {
|
||||
"style": "space",
|
||||
"template": "space-base",
|
||||
"icons": ["assets/icons/pack1/", "assets/icons/pack2/"]
|
||||
},
|
||||
"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/spaceship1.jpeg",
|
||||
"footerImage": "assets/footers/planet1.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"iconPack": "pack1"
|
||||
},
|
||||
{
|
||||
"task": "5 × N ± C, где N от 1 до 5, C от 1 до 6. Знак ± выбирается случайно",
|
||||
"problemCount": 20,
|
||||
"heroImage": "assets/hero-images/spaceship2.jpeg",
|
||||
"footerImage": "assets/footers/planet2.jpeg",
|
||||
"heroDirection": "row",
|
||||
"iconPack": "pack1"
|
||||
},
|
||||
{
|
||||
"task": "A × B ± C, где A и B от 1 до 4, C от 1 до 8. Знак ± выбирается случайно",
|
||||
"problemCount": 20,
|
||||
"heroImage": "assets/hero-images/spaceship3.png",
|
||||
"footerImage": "assets/footers/planet3.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"iconPack": "pack1"
|
||||
},
|
||||
{
|
||||
"task": "A + B + C, где A от 12 до 24, B ±(от 6 до 10), C ±(от 2 до 5). Результат от 0 до 40 включительно",
|
||||
"problemCount": 20,
|
||||
"heroImage": "assets/hero-images/spaceship4.jpeg",
|
||||
"footerImage": "assets/footers/planet4.jpeg",
|
||||
"heroDirection": "row",
|
||||
"iconPack": "pack2"
|
||||
},
|
||||
{
|
||||
"task": "5 + 5 + 5 (сложение пятерок: 2, 3 или 4 штуки) ИЛИ 5 × N (N от 1 до 12) ИЛИ 5 × N ± 5",
|
||||
"problemCount": 20,
|
||||
"heroImage": "assets/hero-images/spaceship5.jpeg",
|
||||
"footerImage": "assets/footers/planet5.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"iconPack": "pack2"
|
||||
},
|
||||
{
|
||||
"task": "A × B + C × D, где A от 2 до 4, B от 1 до 3, C от 2 до 3, D от 1 до 2",
|
||||
"problemCount": 20,
|
||||
"heroImage": "assets/hero-images/spaceship6.jpeg",
|
||||
"footerImage": "assets/footers/planet6.jpeg",
|
||||
"heroDirection": "row",
|
||||
"iconPack": "pack2"
|
||||
},
|
||||
{
|
||||
"task": "A + B ± C, где A от 8 до 16, B от 4 до 8, C от 1 до 3. Знак ± выбирается случайно",
|
||||
"problemCount": 20,
|
||||
"heroImage": "assets/hero-images/spaceship7.jpeg",
|
||||
"footerImage": "assets/footers/planet7.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"iconPack": "pack1"
|
||||
},
|
||||
{
|
||||
"task": "5 × N ± C, где N от 1 до 5, C от 1 до 6. Знак ± выбирается случайно",
|
||||
"problemCount": 20,
|
||||
"heroImage": "assets/hero-images/spaceship8.jpeg",
|
||||
"footerImage": "assets/footers/planet8.jpeg",
|
||||
"heroDirection": "row",
|
||||
"iconPack": "pack1"
|
||||
},
|
||||
{
|
||||
"task": "A × B ± C, где A и B от 1 до 4, C от 1 до 8. Знак ± выбирается случайно",
|
||||
"problemCount": 20,
|
||||
"heroImage": "assets/hero-images/spaceship9.jpeg",
|
||||
"footerImage": "assets/footers/planet9.jpeg",
|
||||
"heroDirection": "row-reverse",
|
||||
"iconPack": "pack1"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user