- @foreach (var level in world.Levels)
- {
- bool isUnlocked = Profile.UnlockedLevels.Contains(level.Id);
- bool isCompleted = Profile.CompletedLevels.Contains(level.Id);
+
+
+
+
+ @for (int i = 0; i < Worlds.Count; i++)
+ {
+ var w = Worlds[i];
+ var worldIndex = i + 1;
+ var isSelected = SelectedWorldIndex == worldIndex;
+ var isWorldUnlocked = w.Levels.Any(l => Profile.UnlockedLevels.Contains(l.Id));
+ var completedInWorld = w.Levels.Count(l => Profile.CompletedLevels.Contains(l.Id));
+ var totalInWorld = w.Levels.Count;
+ var isWorldCompleted = totalInWorld > 0 && completedInWorld == totalInWorld;
-
@@ -57,6 +89,9 @@
private PlayerProfile Profile { get; set; } = new();
private Level? SelectedLevel { get; set; }
+ private bool IsTransitioning { get; set; } = false;
+ private string TransitionTargetText { get; set; } = string.Empty;
+
protected override async Task OnInitializedAsync()
{
try
@@ -85,19 +120,44 @@
await Storage.SaveProfileAsync(Profile);
}
- private void HandleLevelSelected(Level level)
+ private async Task HandleLevelSelected(Level level)
{
+ TransitionTargetText = $"{level.Name} (Protivník: {level.Enemy.Name})";
+ IsTransitioning = true;
+ StateHasChanged();
+
+ await Task.Delay(850);
+
SelectedLevel = level;
CurrentScreen = ScreenType.Battle;
+ IsTransitioning = false;
+ StateHasChanged();
}
private async Task HandleLevelCompleted(Level completedLevel)
+ {
+ UnlockNextLevel(completedLevel);
+ await Storage.SaveProfileAsync(Profile);
+ CurrentScreen = ScreenType.WorldMap;
+ }
+
+ private async Task HandleNextLevelRequested(Level nextLevel)
+ {
+ if (SelectedLevel != null)
+ {
+ UnlockNextLevel(SelectedLevel);
+ await Storage.SaveProfileAsync(Profile);
+ }
+
+ await HandleLevelSelected(nextLevel);
+ }
+
+ private void UnlockNextLevel(Level completedLevel)
{
Profile.CompletedLevels.Add(completedLevel.Id);
Profile.TotalStars += completedLevel.IsBoss ? 3 : 1;
Profile.Gold += completedLevel.IsBoss ? 50 : 20;
- // Unlock next level in current world
var worlds = DataLoader.GetWorldsForGrade(Profile.SelectedGrade);
var currentWorld = worlds.FirstOrDefault(w => w.Levels.Any(l => l.Id == completedLevel.Id));
if (currentWorld != null)
@@ -109,7 +169,6 @@
}
else
{
- // Unlock first level of next world
var nextWorldIndex = worlds.IndexOf(currentWorld) + 1;
if (nextWorldIndex < worlds.Count && worlds[nextWorldIndex].Levels.Any())
{
@@ -117,8 +176,5 @@
}
}
}
-
- await Storage.SaveProfileAsync(Profile);
- CurrentScreen = ScreenType.WorldMap;
}
}
diff --git a/src/CiselnaVyprava/Services/GameDataLoader.cs b/src/CiselnaVyprava/Services/GameDataLoader.cs
index 3e7e104..41416e0 100644
--- a/src/CiselnaVyprava/Services/GameDataLoader.cs
+++ b/src/CiselnaVyprava/Services/GameDataLoader.cs
@@ -10,6 +10,7 @@ public interface IGameDataLoader
List
Heroes { get; }
List GetWorldsForGrade(int grade);
Hero? GetHero(string id);
+ Level? GetNextLevel(int grade, string currentLevelId);
}
public class GameDataLoader : IGameDataLoader
@@ -60,4 +61,29 @@ public class GameDataLoader : IGameDataLoader
return _heroes.FirstOrDefault(h => h.Id.Equals(id, StringComparison.OrdinalIgnoreCase))
?? _heroes.FirstOrDefault();
}
+
+ public Level? GetNextLevel(int grade, string currentLevelId)
+ {
+ var worlds = GetWorldsForGrade(grade);
+ for (int w = 0; w < worlds.Count; w++)
+ {
+ var world = worlds[w];
+ for (int l = 0; l < world.Levels.Count; l++)
+ {
+ if (world.Levels[l].Id == currentLevelId)
+ {
+ if (l + 1 < world.Levels.Count)
+ {
+ return world.Levels[l + 1];
+ }
+ else if (w + 1 < worlds.Count && worlds[w + 1].Levels.Any())
+ {
+ return worlds[w + 1].Levels.First();
+ }
+ return null;
+ }
+ }
+ }
+ return null;
+ }
}
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_attack_p1.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_attack_p1.png
new file mode 100644
index 0000000..6110b71
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_attack_p1.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_attack_p2.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_attack_p2.png
new file mode 100644
index 0000000..6110b71
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_attack_p2.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_attack_p3.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_attack_p3.png
new file mode 100644
index 0000000..6110b71
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_attack_p3.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_attack_p4.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_attack_p4.png
new file mode 100644
index 0000000..6110b71
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_attack_p4.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_defend_p1.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_defend_p1.png
new file mode 100644
index 0000000..69d38d6
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_defend_p1.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_defend_p2.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_defend_p2.png
new file mode 100644
index 0000000..69d38d6
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_defend_p2.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_defend_p3.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_defend_p3.png
new file mode 100644
index 0000000..69d38d6
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_defend_p3.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_defend_p4.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_defend_p4.png
new file mode 100644
index 0000000..69d38d6
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_defend_p4.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_hurt_p1.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_hurt_p1.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_hurt_p1.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_hurt_p2.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_hurt_p2.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_hurt_p2.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_hurt_p3.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_hurt_p3.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_hurt_p3.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_hurt_p4.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_hurt_p4.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_hurt_p4.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_idle_p1.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_idle_p1.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_idle_p1.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_idle_p2.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_idle_p2.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_idle_p2.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_idle_p3.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_idle_p3.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_idle_p3.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_idle_p4.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_idle_p4.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/archer_idle_p4.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_attack_p1.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_attack_p1.png
new file mode 100644
index 0000000..6110b71
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_attack_p1.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_attack_p2.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_attack_p2.png
new file mode 100644
index 0000000..6110b71
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_attack_p2.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_attack_p3.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_attack_p3.png
new file mode 100644
index 0000000..6110b71
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_attack_p3.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_attack_p4.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_attack_p4.png
new file mode 100644
index 0000000..6110b71
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_attack_p4.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_defend_p1.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_defend_p1.png
new file mode 100644
index 0000000..69d38d6
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_defend_p1.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_defend_p2.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_defend_p2.png
new file mode 100644
index 0000000..69d38d6
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_defend_p2.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_defend_p3.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_defend_p3.png
new file mode 100644
index 0000000..69d38d6
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_defend_p3.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_defend_p4.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_defend_p4.png
new file mode 100644
index 0000000..69d38d6
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_defend_p4.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_hurt_p1.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_hurt_p1.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_hurt_p1.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_hurt_p2.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_hurt_p2.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_hurt_p2.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_hurt_p3.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_hurt_p3.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_hurt_p3.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_hurt_p4.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_hurt_p4.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_hurt_p4.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_idle_p1.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_idle_p1.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_idle_p1.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_idle_p2.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_idle_p2.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_idle_p2.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_idle_p3.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_idle_p3.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_idle_p3.png differ
diff --git a/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_idle_p4.png b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_idle_p4.png
new file mode 100644
index 0000000..7de3dea
Binary files /dev/null and b/src/CiselnaVyprava/wwwroot/assets/images/heroes/mage_idle_p4.png differ
diff --git a/src/CiselnaVyprava/wwwroot/css/app.css b/src/CiselnaVyprava/wwwroot/css/app.css
index 7496b0c..a666f19 100644
--- a/src/CiselnaVyprava/wwwroot/css/app.css
+++ b/src/CiselnaVyprava/wwwroot/css/app.css
@@ -175,256 +175,1183 @@ html, body {
}
/* ========================================================
- CHARACTER SELECT (100% VIEWPORT COMPACT 2-COLUMN)
+ WIZARD NEW GAME FLOW (GRADE -> HERO -> NAME & START)
======================================================== */
-.character-select-screen {
+.wizard-screen {
height: 100%;
+ width: 100%;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
+ padding: clamp(6px, 1.5vh, 16px);
}
-.select-card-compact {
+.wizard-container {
background: var(--color-parchment);
border: 4px solid var(--color-parchment-border);
border-radius: 20px;
box-shadow: var(--shadow-storybook);
- padding: clamp(12px, 2vh, 22px);
+ padding: clamp(10px, 1.8vh, 20px);
width: 100%;
- max-width: 900px;
+ max-width: 980px;
max-height: 96vh;
display: flex;
flex-direction: column;
justify-content: space-between;
+ overflow: hidden;
}
-.select-header {
+.wizard-top-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: clamp(4px, 1vh, 10px);
+ flex: 0 0 auto;
+}
+
+.btn-wizard-back {
+ background: #fff;
+ border: 2px solid #bdc3c7;
+ border-radius: 8px;
+ padding: 4px 12px;
+ font-weight: 700;
+ font-family: var(--font-main);
+ font-size: clamp(0.75rem, 1.6vh, 0.9rem);
+ cursor: pointer;
+ transition: all 0.15s ease;
+ color: #2c3e50;
+}
+
+.btn-wizard-back:hover {
+ background: #ecf0f1;
+ border-color: #95a5a6;
+}
+
+.wizard-stepper {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ font-size: clamp(0.75rem, 1.6vh, 0.9rem);
+ font-weight: 700;
+}
+
+.step-badge {
+ padding: 3px 10px;
+ border-radius: 12px;
+ background: #e2dcd0;
+ color: #7f8c8d;
+ transition: all 0.2s ease;
+}
+
+.step-badge.active {
+ background: var(--color-gold);
+ color: white;
+ box-shadow: 0 2px 6px rgba(243, 156, 18, 0.4);
+}
+
+.step-badge.completed {
+ background: #d4efdf;
+ color: #1e8449;
+ cursor: pointer;
+}
+
+.step-divider {
+ color: #bdc3c7;
+ font-size: 0.8rem;
+}
+
+.wizard-header {
text-align: center;
- margin-bottom: clamp(6px, 1.2vh, 12px);
+ margin-bottom: clamp(6px, 1.2vh, 14px);
+ flex: 0 0 auto;
}
-.select-header .game-main-title {
- font-size: clamp(1.6rem, 3.8vh, 2.2rem);
+.wizard-title {
+ font-size: clamp(1.4rem, 3.2vh, 2rem);
color: var(--color-parchment-border);
margin: 0;
- text-shadow: none;
+ font-weight: 800;
}
-.select-header .subtitle {
- font-size: clamp(0.85rem, 1.8vh, 1rem);
+.wizard-subtitle {
+ font-size: clamp(0.8rem, 1.6vh, 0.95rem);
color: #7f8c8d;
margin: 2px 0 0 0;
}
-.select-content-grid {
+/* --- STEP 1: GRADES GRID --- */
+.grades-grid {
display: grid;
- grid-template-columns: 1fr 1fr;
- gap: clamp(10px, 2vw, 20px);
- align-items: start;
+ grid-template-columns: repeat(3, 1fr);
+ gap: clamp(10px, 1.5vw, 18px);
+ flex: 1 1 auto;
+ align-items: stretch;
+ min-height: 0;
}
-.select-col-left, .select-col-right {
+.grade-card {
+ background: white;
+ border: 3px solid #d5dbdb;
+ border-radius: 18px;
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ text-align: center;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ box-shadow: 0 4px 10px rgba(0,0,0,0.06);
+ overflow: hidden;
+}
+
+.grade-card:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 10px 22px rgba(0,0,0,0.15);
+}
+
+.grade-1-card { border-color: #3498db; }
+.grade-1-card:hover, .grade-1-card.selected { border-color: #2980b9; box-shadow: 0 8px 22px rgba(52, 152, 219, 0.35); }
+
+.grade-2-card { border-color: #e67e22; }
+.grade-2-card:hover, .grade-2-card.selected { border-color: #d35400; box-shadow: 0 8px 22px rgba(230, 126, 34, 0.35); }
+
+.grade-3-card { border-color: #9b59b6; }
+.grade-3-card:hover, .grade-3-card.selected { border-color: #8e44ad; box-shadow: 0 8px 22px rgba(155, 89, 182, 0.35); }
+
+.grade-banner-stage {
+ width: 100%;
+ height: clamp(75px, 14vh, 105px);
+ position: relative;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.grade-banner-overlay {
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(180deg, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0.5) 100%);
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 2px;
+}
+
+.grade-card-icon {
+ font-size: clamp(1.4rem, 3vh, 2rem);
+ filter: drop-shadow(0 2px 4px rgba(0,0,0,0.4));
+}
+
+.grade-card-badge {
+ font-size: clamp(0.7rem, 1.4vh, 0.8rem);
+ font-weight: 800;
+ padding: 2px 10px;
+ border-radius: 8px;
+ color: white;
+ letter-spacing: 0.5px;
+ box-shadow: 0 2px 6px rgba(0,0,0,0.3);
+}
+
+.grade-1-badge { background: #3498db; }
+.grade-2-badge { background: #e67e22; }
+.grade-3-badge { background: #9b59b6; }
+
+.grade-card-content {
+ padding: clamp(8px, 1.4vh, 14px);
+ display: flex;
+ flex-direction: column;
+ flex: 1 1 auto;
+ align-items: center;
+}
+
+.grade-card-title {
+ margin: 0 0 2px 0;
+ font-size: clamp(1.1rem, 2.3vh, 1.3rem);
+ color: #2c3e50;
+ font-weight: 800;
+}
+
+.grade-card-desc {
+ font-size: clamp(0.72rem, 1.4vh, 0.82rem);
+ color: #7f8c8d;
+ margin: 0 0 clamp(6px, 1vh, 8px) 0;
+ min-height: 2.4em;
+ line-height: 1.2;
+}
+
+.grade-topics-list {
+ list-style: none;
+ padding: 0;
+ margin: 0 0 clamp(8px, 1.4vh, 12px) 0;
+ text-align: left;
+ font-size: clamp(0.72rem, 1.35vh, 0.82rem);
+ color: #34495e;
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ flex: 1 1 auto;
+ width: 100%;
+}
+
+.grade-topics-list li {
+ background: #f8f9f9;
+ padding: 3px 8px;
+ border-radius: 6px;
+ border-left: 3px solid #bdc3c7;
+}
+
+.grade-1-card .grade-topics-list li { border-left-color: #3498db; }
+.grade-2-card .grade-topics-list li { border-left-color: #e67e22; }
+.grade-3-card .grade-topics-list li { border-left-color: #9b59b6; }
+
+.btn-grade-select {
+ width: 100%;
+ color: white;
+ border: none;
+ border-radius: 10px;
+ padding: clamp(6px, 1.2vh, 10px) 12px;
+ font-weight: 800;
+ font-family: var(--font-main);
+ font-size: clamp(0.85rem, 1.7vh, 0.95rem);
+ cursor: pointer;
+ transition: all 0.15s ease;
+ margin-top: auto;
+}
+
+.btn-grade-1 { background: #3498db; box-shadow: 0 3px 0 #2471a3; }
+.btn-grade-1:hover { background: #2980b9; transform: translateY(-1px); }
+
+.btn-grade-2 { background: #e67e22; box-shadow: 0 3px 0 #b95c00; }
+.btn-grade-2:hover { background: #d35400; transform: translateY(-1px); }
+
+.btn-grade-3 { background: #9b59b6; box-shadow: 0 3px 0 #6c3483; }
+.btn-grade-3:hover { background: #8e44ad; transform: translateY(-1px); }
+
+/* --- STEP 2: HERO SHOWCASE GRID --- */
+.hero-showcase-grid {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: clamp(10px, 1.5vw, 18px);
+ flex: 1 1 auto;
+ align-items: stretch;
+ min-height: 0;
+}
+
+.hero-showcase-card {
+ background: white;
+ border: 3px solid #d5dbdb;
+ border-radius: 16px;
+ padding: clamp(8px, 1.4vh, 14px);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ box-shadow: 0 4px 10px rgba(0,0,0,0.05);
+ position: relative;
+ overflow: hidden;
+}
+
+.hero-showcase-card:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 8px 20px rgba(0,0,0,0.15);
+}
+
+.hero-theme-knight { border-color: #f39c12; }
+.hero-theme-knight:hover, .hero-theme-knight.selected { border-color: #d35400; background: #fef9e7; }
+
+.hero-theme-mage { border-color: #9b59b6; }
+.hero-theme-mage:hover, .hero-theme-mage.selected { border-color: #8e44ad; background: #fbf6fd; }
+
+.hero-theme-archer { border-color: #27ae60; }
+.hero-theme-archer:hover, .hero-theme-archer.selected { border-color: #229954; background: #eafaf1; }
+
+.hero-card-banner {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ margin-bottom: 4px;
+}
+
+.hero-crest-icon { font-size: clamp(1.2rem, 2.5vh, 1.5rem); }
+.hero-class-label { font-size: 0.75rem; font-weight: 700; color: #7f8c8d; text-transform: uppercase; }
+
+.hero-portrait-stage {
+ width: 100%;
+ height: clamp(90px, 18vh, 140px);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: relative;
+ margin: 2px 0 6px 0;
+}
+
+.hero-portrait-img {
+ max-height: 100%;
+ max-width: 100%;
+ object-fit: contain;
+ filter: drop-shadow(0 6px 10px rgba(0,0,0,0.25));
+}
+
+.hero-info-box {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 4px;
+ flex: 1 1 auto;
+ width: 100%;
+}
+
+.hero-title-name {
+ margin: 0;
+ font-size: clamp(1rem, 2.2vh, 1.25rem);
+ color: #2c3e50;
+ font-weight: 800;
+}
+
+.hero-lore-desc {
+ font-size: clamp(0.7rem, 1.4vh, 0.8rem);
+ color: #7f8c8d;
+ margin: 0;
+ min-height: 2.4em;
+ line-height: 1.25;
+}
+
+.hero-skill-pill {
+ background: #f4f6f6;
+ border: 1px dashed #bdc3c7;
+ border-radius: 6px;
+ padding: 2px 8px;
+ font-size: clamp(0.7rem, 1.3vh, 0.8rem);
+ color: #34495e;
+ margin: 2px 0;
+}
+
+.hero-stats-row {
+ display: flex;
+ gap: 6px;
+ margin-bottom: 6px;
+}
+
+.stat-tag {
+ font-size: 0.7rem;
+ font-weight: 700;
+ background: rgba(0,0,0,0.05);
+ padding: 2px 6px;
+ border-radius: 4px;
+ color: #2c3e50;
+}
+
+.btn-hero-select {
+ width: 100%;
+ background: var(--color-forest);
+ color: white;
+ border: none;
+ border-radius: 10px;
+ padding: clamp(6px, 1.2vh, 10px) 12px;
+ font-weight: 800;
+ font-family: var(--font-main);
+ font-size: clamp(0.85rem, 1.7vh, 0.95rem);
+ cursor: pointer;
+ box-shadow: 0 3px 0 #1e8449;
+ transition: all 0.15s ease;
+}
+
+.btn-hero-select:hover {
+ background: #2ecc71;
+ transform: translateY(-1px);
+}
+
+/* --- STEP 3: NAMING & START QUEST --- */
+.wizard-name-container {
+ max-width: 860px;
+}
+
+.naming-content-stage {
+ display: grid;
+ grid-template-columns: 1fr 1.3fr;
+ gap: clamp(14px, 2.5vw, 24px);
+ align-items: center;
+ flex: 1 1 auto;
+ min-height: 0;
+}
+
+.naming-hero-preview {
+ background: white;
+ border: 3px solid var(--color-parchment-border);
+ border-radius: 16px;
+ padding: clamp(12px, 2vh, 18px);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ box-shadow: 0 4px 12px rgba(0,0,0,0.06);
+}
+
+.hero-stage-pedestal {
+ width: 100%;
+ height: clamp(110px, 22vh, 160px);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background: radial-gradient(circle, rgba(243, 156, 18, 0.2) 0%, rgba(255, 255, 255, 0) 70%);
+ border-radius: 12px;
+ margin-bottom: 6px;
+}
+
+.naming-hero-img {
+ max-height: 100%;
+ max-width: 100%;
+ object-fit: contain;
+ filter: drop-shadow(0 8px 14px rgba(0,0,0,0.3));
+}
+
+.naming-badges-row {
+ display: flex;
+ gap: 6px;
+ margin-bottom: 6px;
+}
+
+.grade-pill-badge {
+ background: var(--color-gold);
+ color: white;
+ font-size: 0.75rem;
+ font-weight: 700;
+ padding: 2px 8px;
+ border-radius: 8px;
+}
+
+.hero-pill-badge {
+ background: #34495e;
+ color: white;
+ font-size: 0.75rem;
+ font-weight: 700;
+ padding: 2px 8px;
+ border-radius: 8px;
+}
+
+.naming-stat-summary {
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+ font-size: clamp(0.7rem, 1.4vh, 0.8rem);
+ color: #566573;
+ font-weight: 600;
+}
+
+.naming-form-box {
display: flex;
flex-direction: column;
gap: clamp(8px, 1.5vh, 14px);
}
-.selection-section {
- margin-bottom: 0;
+.form-group {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
}
-.step-title {
+.form-label {
font-size: clamp(0.95rem, 2vh, 1.15rem);
- color: #34495e;
- margin: 0 0 6px 0;
- border-bottom: 2px dashed #d5dbdb;
- padding-bottom: 3px;
- font-weight: 700;
+ font-weight: 800;
+ color: #2c3e50;
}
-.grade-toggle-group {
- display: flex;
- flex-direction: column;
- gap: 6px;
-}
-
-.grade-btn {
- background: #fff;
- border: 2px solid #bdc3c7;
- border-radius: 10px;
- padding: clamp(6px, 1vh, 10px) 12px;
- cursor: pointer;
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-family: var(--font-main);
- transition: all 0.15s ease;
-}
-
-.grade-btn.active {
- border-color: var(--color-gold);
- background: #fef9e7;
- box-shadow: 0 2px 8px rgba(243, 156, 18, 0.3);
-}
-
-.grade-badge { font-size: clamp(0.9rem, 2vh, 1.05rem); font-weight: 700; color: #2c3e50; }
-.grade-desc { font-size: 0.8rem; color: #7f8c8d; }
-
-.heroes-grid {
- display: flex;
- flex-direction: column;
- gap: 8px;
-}
-
-.hero-card {
- background: #fff;
- border: 2px solid #bdc3c7;
- border-radius: 12px;
- padding: clamp(6px, 1.2vh, 10px) 12px;
- display: grid;
- grid-template-columns: auto 1fr auto;
- align-items: center;
- gap: 12px;
- cursor: pointer;
- transition: all 0.15s ease;
- text-align: left;
-}
-
-.hero-card.selected-card {
- border-color: var(--color-gold);
- background: #fef9e7;
- box-shadow: 0 3px 10px rgba(243, 156, 18, 0.35);
-}
-
-.hero-avatar { font-size: 1.8rem; }
-.hero-name { margin: 0; font-size: 1rem; color: #2c3e50; font-weight: 700; }
-.hero-title { font-size: 0.75rem; color: #95a5a6; display: block; }
-.hero-skill { font-size: 0.75rem; background: #eaeded; padding: 2px 6px; border-radius: 6px; }
-
-.name-field-row {
+.name-input-with-dice {
display: flex;
gap: 8px;
+ align-items: stretch;
+ width: 100%;
}
-.hero-name-input {
+.hero-name-big-input {
flex: 1;
- padding: clamp(8px, 1.5vh, 12px);
- font-size: clamp(0.9rem, 2vh, 1.05rem);
+ padding: clamp(8px, 1.5vh, 12px) 14px;
+ font-size: clamp(1rem, 2.2vh, 1.25rem);
font-family: var(--font-main);
- border: 2px solid #bdc3c7;
- border-radius: 10px;
+ font-weight: 700;
+ border: 3px solid var(--color-gold);
+ border-radius: 12px;
+ background: white;
outline: none;
+ box-shadow: inset 0 2px 4px rgba(0,0,0,0.06);
+ color: #2c3e50;
}
-.btn-start-quest {
- background: var(--color-forest);
- color: white;
- font-size: clamp(0.95rem, 2vh, 1.15rem);
- font-weight: 700;
- font-family: var(--font-main);
- border: none;
- border-radius: 10px;
- padding: clamp(8px, 1.5vh, 12px) clamp(12px, 2vw, 20px);
+.hero-name-big-input:focus {
+ border-color: #d35400;
+ box-shadow: 0 0 10px rgba(243, 156, 18, 0.4);
+}
+
+.btn-dice-randomizer {
+ background: #fef9e7;
+ border: 2px solid var(--color-gold);
+ border-radius: 12px;
+ padding: clamp(6px, 1vh, 10px) 14px;
cursor: pointer;
- box-shadow: 0 3px 0 #1e8449;
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ font-family: var(--font-main);
+ font-weight: 800;
+ font-size: clamp(0.8rem, 1.6vh, 0.95rem);
+ color: #b7950b;
+ box-shadow: 0 3px 0 var(--color-gold-dark);
+ transition: all 0.15s ease;
white-space: nowrap;
}
+.btn-dice-randomizer:hover {
+ background: #fcf3cf;
+ transform: translateY(-2px);
+ box-shadow: 0 5px 0 var(--color-gold-dark);
+}
+
+.btn-dice-randomizer:active, .btn-dice-randomizer.rolling {
+ transform: translateY(2px);
+ box-shadow: 0 1px 0 var(--color-gold-dark);
+}
+
+.dice-icon {
+ font-size: clamp(1.3rem, 2.8vh, 1.7rem);
+ display: inline-block;
+ transition: transform 0.3s ease;
+}
+
+.btn-dice-randomizer.rolling .dice-icon {
+ animation: diceSpin 0.35s ease-in-out;
+}
+
+@keyframes diceSpin {
+ 0% { transform: rotate(0deg) scale(1); }
+ 50% { transform: rotate(180deg) scale(1.3); }
+ 100% { transform: rotate(360deg) scale(1); }
+}
+
+.quick-names-section {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+
+.quick-names-title {
+ font-size: 0.8rem;
+ color: #7f8c8d;
+ font-weight: 600;
+}
+
+.quick-names-grid {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px;
+}
+
+.name-chip-btn {
+ background: white;
+ border: 1.5px solid #bdc3c7;
+ border-radius: 8px;
+ padding: 3px 10px;
+ font-size: clamp(0.75rem, 1.5vh, 0.85rem);
+ font-weight: 600;
+ font-family: var(--font-main);
+ color: #34495e;
+ cursor: pointer;
+ transition: all 0.15s ease;
+}
+
+.name-chip-btn:hover {
+ border-color: var(--color-gold);
+ background: #fef9e7;
+}
+
+.name-chip-btn.active-chip {
+ background: var(--color-gold);
+ border-color: var(--color-gold-dark);
+ color: white;
+ font-weight: 700;
+}
+
+.naming-action-footer {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ margin-top: 4px;
+}
+
+.btn-grand-start {
+ background: linear-gradient(180deg, #2ecc71 0%, #27ae60 100%);
+ color: white;
+ font-size: clamp(1.05rem, 2.4vh, 1.3rem);
+ font-weight: 800;
+ font-family: var(--font-main);
+ border: none;
+ border-radius: 12px;
+ padding: clamp(10px, 2vh, 16px);
+ cursor: pointer;
+ box-shadow: 0 4px 0 #1e8449, 0 6px 16px rgba(39, 174, 96, 0.4);
+ transition: all 0.15s ease;
+ text-shadow: 1px 1px 2px rgba(0,0,0,0.2);
+}
+
+.btn-grand-start:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 6px 0 #1e8449, 0 10px 22px rgba(39, 174, 96, 0.5);
+}
+
+.btn-grand-start:active {
+ transform: translateY(2px);
+ box-shadow: 0 2px 0 #1e8449;
+}
+
+.autosave-notice {
+ font-size: 0.75rem;
+ color: #7f8c8d;
+ margin: 0;
+ text-align: center;
+}
+
/* ========================================================
- WORLD MAP (100% VIEWPORT FIT)
+ WORLD MAP & RICH LEVEL CARDS (100% VIEWPORT FIT)
======================================================== */
.world-map-screen {
height: 100%;
+ width: 100%;
display: flex;
flex-direction: column;
- gap: clamp(8px, 1.5vh, 14px);
+ gap: clamp(6px, 1.2vh, 12px);
overflow: hidden;
+ padding: clamp(4px, 1vh, 10px);
}
.map-top-bar {
background: var(--color-parchment);
border: 3px solid var(--color-parchment-border);
- border-radius: 12px;
- padding: clamp(6px, 1vh, 10px) 16px;
+ border-radius: 14px;
+ padding: clamp(4px, 0.8vh, 8px) 14px;
display: flex;
justify-content: space-between;
align-items: center;
flex: 0 0 auto;
+ box-shadow: 0 4px 10px rgba(0,0,0,0.1);
}
.player-pill {
display: flex;
align-items: center;
- gap: 8px;
- font-weight: 700;
- font-size: clamp(0.9rem, 2vh, 1.1rem);
+ gap: 10px;
+}
+
+.mini-hero-avatar {
+ width: clamp(34px, 5vh, 44px);
+ height: clamp(34px, 5vh, 44px);
+ object-fit: contain;
+ border-radius: 50%;
+ background: #fff;
+ border: 2px solid var(--color-gold);
+ padding: 2px;
+ box-shadow: 0 2px 6px rgba(0,0,0,0.15);
+}
+
+.player-info-text {
+ display: flex;
+ flex-direction: column;
+ text-align: left;
+}
+
+.player-name {
+ font-weight: 800;
+ font-size: clamp(0.95rem, 2vh, 1.15rem);
+ color: #2c3e50;
+ line-height: 1.1;
}
.grade-tag {
background: var(--color-gold);
color: white;
font-size: 0.75rem;
- padding: 2px 6px;
+ font-weight: 700;
+ padding: 1px 6px;
border-radius: 6px;
+ margin-top: 2px;
+ display: inline-block;
+ width: fit-content;
}
-.btn-change-hero {
- background: #ecf0f1;
- border: 2px solid #bdc3c7;
- border-radius: 8px;
- padding: 4px 10px;
- font-family: var(--font-main);
- cursor: pointer;
- font-weight: 600;
- font-size: 0.85rem;
-}
-
-.worlds-carousel {
- flex: 1 1 auto;
- overflow-y: auto;
+.stats-pill-group {
display: flex;
- flex-direction: column;
- gap: clamp(8px, 1.5vh, 14px);
- padding-right: 4px;
+ gap: 8px;
}
-.world-card {
- background: var(--color-parchment);
- border: 3px solid var(--color-parchment-border);
- border-radius: 16px;
- padding: clamp(10px, 2vh, 18px);
- box-shadow: var(--shadow-storybook);
-}
-
-.world-header h2 { margin: 0; font-size: clamp(1.1rem, 2.5vh, 1.4rem); color: #2c3e50; }
-.world-header p { color: #7f8c8d; margin: 2px 0 clamp(8px, 1.5vh, 12px) 0; font-size: clamp(0.8rem, 1.8vh, 0.95rem); }
-
-.levels-path {
- display: flex;
- gap: clamp(8px, 1.5vw, 14px);
- flex-wrap: wrap;
-}
-
-.level-node {
+.stat-badge {
background: white;
border: 2px solid #bdc3c7;
- border-radius: 12px;
- padding: clamp(8px, 1.5vh, 12px) 14px;
+ border-radius: 8px;
+ padding: 3px 10px;
+ font-size: clamp(0.8rem, 1.6vh, 0.95rem);
+ font-weight: 700;
+ color: #2c3e50;
+}
+
+.stat-badge.stars-badge { border-color: var(--color-gold); background: #fefcf5; }
+.stat-badge.gold-badge { border-color: #f1c40f; background: #fffdf2; }
+
+.btn-top-action {
+ background: #fff;
+ border: 2px solid #bdc3c7;
+ border-radius: 8px;
+ padding: 4px 12px;
+ font-family: var(--font-main);
+ font-weight: 700;
+ font-size: clamp(0.75rem, 1.6vh, 0.85rem);
+ cursor: pointer;
+ transition: all 0.15s ease;
+ color: #34495e;
+}
+
+.btn-top-action:hover {
+ background: #f4f6f7;
+ border-color: var(--color-gold);
+ transform: translateY(-1px);
+}
+
+/* WORLD MAP CONTENT AREA */
+.world-map-content {
+ flex: 1 1 auto;
display: flex;
flex-direction: column;
+ gap: clamp(6px, 1.2vh, 10px);
+ min-height: 0;
+ overflow: hidden;
+}
+
+/* WORLD TABS NAV */
+.world-tabs-nav {
+ display: flex;
+ gap: clamp(6px, 1vw, 12px);
+ flex: 0 0 auto;
+ overflow-x: auto;
+ padding-bottom: 2px;
+}
+
+.world-tab-btn {
+ flex: 1 1 auto;
+ min-width: 120px;
+ background: #fff;
+ border: 2px solid #bdc3c7;
+ border-radius: 12px;
+ padding: clamp(6px, 1vh, 10px) 10px;
+ display: flex;
align-items: center;
- min-width: 110px;
+ justify-content: center;
+ gap: 6px;
cursor: pointer;
font-family: var(--font-main);
transition: all 0.15s ease;
+ box-shadow: 0 2px 6px rgba(0,0,0,0.05);
}
-.level-node.unlocked { border-color: var(--color-gold); box-shadow: 0 3px 6px rgba(0,0,0,0.1); }
-.level-node.completed { border-color: var(--color-forest); background: #e8f8f5; }
-.level-node.boss-node { border-color: var(--color-crimson); background: #fdedec; }
-.node-icon { font-size: clamp(1.3rem, 3vh, 1.8rem); margin-bottom: 2px; }
-.level-title { font-weight: 700; font-size: clamp(0.8rem, 1.8vh, 0.9rem); }
+.world-tab-btn:hover:not(:disabled) {
+ transform: translateY(-2px);
+ border-color: var(--color-gold);
+}
+
+.world-tab-btn.active {
+ background: var(--color-gold);
+ border-color: var(--color-gold-dark);
+ color: white;
+ box-shadow: 0 4px 10px rgba(243, 156, 18, 0.4);
+}
+
+.world-tab-btn.locked {
+ opacity: 0.6;
+ background: #eaeded;
+ cursor: not-allowed;
+ border-style: dashed;
+}
+
+.world-tab-btn.world-completed {
+ border-color: #27ae60;
+}
+
+.world-tab-btn.active.world-completed {
+ background: #27ae60;
+ border-color: #1e8449;
+}
+
+.world-tab-icon { font-size: clamp(1rem, 2.2vh, 1.3rem); }
+.world-tab-label { font-weight: 800; font-size: clamp(0.8rem, 1.7vh, 0.95rem); }
+.world-tab-progress {
+ font-size: 0.75rem;
+ font-weight: 700;
+ background: rgba(0,0,0,0.08);
+ padding: 1px 6px;
+ border-radius: 6px;
+}
+
+.world-tab-btn.active .world-tab-progress {
+ background: rgba(255, 255, 255, 0.25);
+ color: white;
+}
+
+/* ACTIVE WORLD CONTAINER */
+.active-world-card {
+ flex: 1 1 auto;
+ background: var(--color-parchment);
+ border: 4px solid var(--color-parchment-border);
+ border-radius: 18px;
+ box-shadow: var(--shadow-storybook);
+ padding: clamp(8px, 1.5vh, 16px);
+ display: flex;
+ flex-direction: column;
+ gap: clamp(6px, 1.2vh, 12px);
+ min-height: 0;
+ overflow: hidden;
+}
+
+.world-header-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ border-bottom: 2px dashed #d5dbdb;
+ padding-bottom: clamp(4px, 0.8vh, 8px);
+ flex: 0 0 auto;
+}
+
+.world-title-col { text-align: left; }
+.active-world-title {
+ margin: 0;
+ font-size: clamp(1.1rem, 2.4vh, 1.4rem);
+ color: #2c3e50;
+ font-weight: 800;
+}
+
+.active-world-desc {
+ margin: 2px 0 0 0;
+ color: #7f8c8d;
+ font-size: clamp(0.75rem, 1.5vh, 0.85rem);
+}
+
+.world-progress-col {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ gap: 3px;
+}
+
+.progress-label-row {
+ font-size: clamp(0.75rem, 1.5vh, 0.85rem);
+ color: #34495e;
+}
+
+.world-progress-bar {
+ width: clamp(120px, 15vw, 180px);
+ height: 10px;
+ background: #e0d7c6;
+ border: 2px solid var(--color-parchment-border);
+ border-radius: 6px;
+ overflow: hidden;
+}
+
+.world-progress-fill {
+ height: 100%;
+ background: linear-gradient(90deg, #f39c12, #27ae60);
+ border-radius: 4px;
+ transition: width 0.4s ease;
+}
+
+/* LEVELS RICH CARDS GRID */
+.levels-rich-grid {
+ flex: 1 1 auto;
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
+ gap: clamp(8px, 1.5vw, 16px);
+ align-items: stretch;
+ min-height: 0;
+ overflow-y: auto;
+ padding: 2px;
+}
+
+.level-rich-card {
+ background: white;
+ border: 3px solid #d5dbdb;
+ border-radius: 16px;
+ padding: clamp(8px, 1.4vh, 12px);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ box-shadow: 0 4px 10px rgba(0,0,0,0.06);
+ position: relative;
+ transition: all 0.2s ease;
+}
+
+.level-rich-card:hover {
+ transform: translateY(-3px);
+ box-shadow: 0 8px 18px rgba(0,0,0,0.12);
+}
+
+/* Card Status Variants */
+.level-rich-card.status-completed {
+ border-color: #27ae60;
+ background: #fdfefe;
+}
+
+.level-rich-card.status-current {
+ border-color: var(--color-gold);
+ background: #fffdf5;
+ box-shadow: 0 0 14px rgba(243, 156, 18, 0.35);
+}
+
+.level-rich-card.status-locked {
+ border-color: #bdc3c7;
+ background: #f2f4f4;
+ opacity: 0.75;
+}
+
+.level-rich-card.boss-card {
+ border-color: var(--color-crimson);
+}
+
+.level-rich-card.boss-card.status-current {
+ box-shadow: 0 0 16px rgba(231, 76, 60, 0.4);
+ background: #fffcfb;
+}
+
+/* Card Status Banner */
+.card-status-banner {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ margin-bottom: 4px;
+ min-height: 20px;
+}
+
+.badge-completed {
+ background: #d4efdf;
+ color: #1e8449;
+ font-size: 0.7rem;
+ font-weight: 800;
+ padding: 2px 8px;
+ border-radius: 6px;
+}
+
+.stars-awarded { font-size: 0.8rem; }
+
+.badge-active {
+ background: #fef9e7;
+ border: 1px solid var(--color-gold);
+ color: #d35400;
+ font-size: 0.7rem;
+ font-weight: 800;
+ padding: 2px 8px;
+ border-radius: 6px;
+}
+
+.badge-boss {
+ background: var(--color-crimson);
+ color: white;
+ font-size: 0.7rem;
+ font-weight: 800;
+ padding: 2px 8px;
+ border-radius: 6px;
+}
+
+.badge-locked {
+ background: #d5dbdb;
+ color: #566573;
+ font-size: 0.7rem;
+ font-weight: 700;
+ padding: 2px 8px;
+ border-radius: 6px;
+}
+
+/* ENEMY AVATAR STAGE */
+.level-enemy-stage {
+ width: 100%;
+ height: clamp(80px, 15vh, 110px);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: relative;
+ margin-bottom: 4px;
+}
+
+.enemy-avatar-wrapper {
+ position: relative;
+ width: clamp(75px, 14vh, 100px);
+ height: clamp(75px, 14vh, 100px);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border-radius: 50%;
+ background: radial-gradient(circle, rgba(255, 255, 255, 0.9) 0%, rgba(240, 240, 240, 0.5) 70%);
+}
+
+.enemy-avatar-wrapper.active-glow {
+ background: radial-gradient(circle, rgba(243, 156, 18, 0.25) 0%, rgba(255, 255, 255, 0) 70%);
+}
+
+.enemy-avatar-wrapper.defeated-glow {
+ background: radial-gradient(circle, rgba(39, 174, 96, 0.2) 0%, rgba(255, 255, 255, 0) 70%);
+}
+
+.enemy-avatar-wrapper.locked-silhouette {
+ filter: grayscale(1) contrast(0.7);
+}
+
+.level-enemy-img {
+ max-height: 85%;
+ max-width: 85%;
+ object-fit: contain;
+ filter: drop-shadow(0 4px 8px rgba(0,0,0,0.25));
+}
+
+.lock-overlay {
+ position: absolute;
+ font-size: 1.8rem;
+ color: #7f8c8d;
+ background: rgba(255, 255, 255, 0.7);
+ width: 44px;
+ height: 44px;
+ border-radius: 50%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.check-overlay {
+ position: absolute;
+ bottom: -2px;
+ right: -2px;
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+ background: #27ae60;
+ color: white;
+ font-weight: 800;
+ font-size: 0.85rem;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border: 2px solid white;
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2);
+}
+
+/* LEVEL INFO BODY */
+.level-info-body {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 3px;
+ flex: 1 1 auto;
+ width: 100%;
+}
+
+.level-number-tag {
+ font-size: 0.7rem;
+ font-weight: 700;
+ color: #95a5a6;
+ text-transform: uppercase;
+}
+
+.level-name-title {
+ margin: 0;
+ font-size: clamp(0.9rem, 1.8vh, 1.1rem);
+ font-weight: 800;
+ color: #2c3e50;
+ line-height: 1.15;
+}
+
+.level-enemy-name {
+ font-size: clamp(0.7rem, 1.3vh, 0.8rem);
+ color: #7f8c8d;
+}
+
+.level-math-pill {
+ background: #f4f6f6;
+ border: 1px solid #d5dbdb;
+ border-radius: 6px;
+ padding: 2px 8px;
+ font-size: clamp(0.68rem, 1.3vh, 0.78rem);
+ color: #34495e;
+ font-weight: 600;
+ margin: 2px 0;
+}
+
+.level-stats-row {
+ display: flex;
+ gap: 6px;
+ margin-top: 2px;
+ margin-bottom: 4px;
+}
+
+.stat-bubble {
+ font-size: 0.68rem;
+ font-weight: 700;
+ background: rgba(0,0,0,0.04);
+ padding: 1px 6px;
+ border-radius: 4px;
+ color: #566573;
+}
+
+/* LEVEL CARD FOOTER BUTTONS */
+.level-card-footer {
+ width: 100%;
+ margin-top: auto;
+}
+
+.btn-level-action {
+ width: 100%;
+ border: none;
+ border-radius: 10px;
+ padding: clamp(6px, 1.2vh, 9px) 10px;
+ font-weight: 800;
+ font-family: var(--font-main);
+ font-size: clamp(0.8rem, 1.6vh, 0.9rem);
+ cursor: pointer;
+ transition: all 0.15s ease;
+}
+
+.btn-replay {
+ background: #f39c12;
+ color: white;
+ box-shadow: 0 3px 0 #b9770e;
+}
+
+.btn-replay:hover {
+ background: #f1c40f;
+ transform: translateY(-1px);
+}
+
+.btn-battle {
+ background: var(--color-forest);
+ color: white;
+ box-shadow: 0 3px 0 #1e8449;
+}
+
+.btn-battle:hover {
+ background: #2ecc71;
+ transform: translateY(-1px);
+}
+
+.btn-boss-battle {
+ background: linear-gradient(180deg, #e74c3c 0%, #c0392b 100%);
+ box-shadow: 0 3px 0 #922b21;
+}
+
+.btn-boss-battle:hover {
+ background: #e74c3c;
+ transform: translateY(-1px);
+}
+
+.btn-locked {
+ background: #d5dbdb;
+ color: #7f8c8d;
+ cursor: not-allowed;
+}
/* ========================================================
BATTLE ARENA (100% VIEWPORT FIT - NO SCROLL)
@@ -661,42 +1588,364 @@ html, body {
.choice-btn:active { transform: translateY(2px); box-shadow: 0 2px 0 var(--color-gold-dark); }
/* VICTORY / DEFEAT CARDS */
-.battle-end-card { padding: clamp(12px, 2vh, 20px); border-radius: 12px; }
-.battle-end-card h2 { font-size: clamp(1.5rem, 3.5vh, 2rem); margin: 0; }
-.battle-end-card p { font-size: clamp(0.95rem, 2vh, 1.1rem); margin: 6px 0 14px 0; }
-.victory-card { background: #d4efdf; border: 3px solid #27ae60; color: #1e8449; }
-.defeat-card { background: #fadbd8; border: 3px solid #e74c3c; color: #922b21; }
-
-.action-btn {
- font-size: clamp(0.95rem, 2vh, 1.15rem);
- font-weight: 700;
- font-family: var(--font-main);
- padding: 8px 22px;
- border: none;
- border-radius: 10px;
- cursor: pointer;
+/* ========================================================
+ VICTORY & DEFEAT CELEBRATION MODAL (FULLSCREEN POPUP)
+ ======================================================== */
+.battle-end-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+ background: rgba(0, 0, 0, 0.75);
+ backdrop-filter: blur(6px);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 9999;
+ padding: clamp(10px, 2vh, 20px);
}
-.next-level-btn { background: var(--color-forest); color: white; }
-.retry-btn { background: var(--color-crimson); color: white; }
+.celebration-modal {
+ background: var(--color-parchment);
+ border: 5px solid var(--color-parchment-border);
+ border-radius: 24px;
+ box-shadow: 0 16px 40px rgba(0, 0, 0, 0.6);
+ padding: clamp(14px, 2.5vh, 24px);
+ width: 100%;
+ max-width: 580px;
+ max-height: 94vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ position: relative;
+ overflow: hidden;
+}
+
+.celebration-modal.victory-theme {
+ border-color: #f39c12;
+ background: linear-gradient(180deg, #fdfbf7 0%, #faebd7 100%);
+}
+
+.celebration-modal.defeat-theme {
+ border-color: #e74c3c;
+ background: linear-gradient(180deg, #fdfefe 0%, #fadbd8 100%);
+}
+
+.celebration-particles {
+ position: absolute;
+ top: 10px;
+ left: 0;
+ right: 0;
+ display: flex;
+ justify-content: space-around;
+ pointer-events: none;
+}
+
+.particle {
+ font-size: clamp(1.4rem, 3vh, 2rem);
+ animation: particleFloat 2s infinite ease-in-out alternate;
+}
+
+.star-p1 { animation-delay: 0s; }
+.star-p2 { animation-delay: 0.4s; }
+.star-p3 { animation-delay: 0.8s; }
+.star-p4 { animation-delay: 1.2s; }
+
+@keyframes particleFloat {
+ 0% { transform: translateY(0) scale(1) rotate(0deg); }
+ 100% { transform: translateY(-12px) scale(1.25) rotate(20deg); }
+}
+
+.celebration-header {
+ margin-bottom: clamp(6px, 1.2vh, 12px);
+}
+
+.celebration-crown {
+ font-size: clamp(2.2rem, 5vh, 3.2rem);
+ display: block;
+ animation: bounce 1s infinite alternate;
+}
+
+.celebration-title {
+ margin: 2px 0;
+ font-size: clamp(1.6rem, 3.8vh, 2.3rem);
+ color: #b7950b;
+ font-weight: 800;
+ text-shadow: 1px 1px 2px rgba(0,0,0,0.1);
+}
+
+.celebration-subtitle {
+ margin: 0;
+ font-size: clamp(0.85rem, 1.8vh, 1rem);
+ color: #7f8c8d;
+ font-weight: 600;
+}
+
+.celebration-body {
+ display: grid;
+ grid-template-columns: 1fr 1.2fr;
+ gap: clamp(10px, 2vw, 18px);
+ align-items: center;
+ width: 100%;
+ margin-bottom: clamp(10px, 2vh, 18px);
+}
+
+.celebration-hero-stage {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: clamp(110px, 22vh, 160px);
+ background: radial-gradient(circle, rgba(243, 156, 18, 0.3) 0%, rgba(255, 255, 255, 0) 70%);
+ border-radius: 16px;
+}
+
+.celebration-hero-img {
+ max-height: 85%;
+ max-width: 85%;
+ object-fit: contain;
+ filter: drop-shadow(0 8px 16px rgba(243, 156, 18, 0.4));
+}
+
+.victory-hero-name {
+ font-size: 0.8rem;
+ font-weight: 700;
+ color: #2c3e50;
+ margin-top: 2px;
+}
+
+.celebration-rewards-card {
+ background: white;
+ border: 2px solid #f39c12;
+ border-radius: 14px;
+ padding: clamp(8px, 1.5vh, 14px);
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ box-shadow: 0 4px 10px rgba(0,0,0,0.06);
+}
+
+.reward-row {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ text-align: left;
+}
+
+.reward-icon { font-size: clamp(1.4rem, 3vh, 1.8rem); }
+
+.reward-info {
+ display: flex;
+ flex-direction: column;
+}
+
+.reward-info strong {
+ font-size: clamp(0.9rem, 1.8vh, 1.1rem);
+ color: #27ae60;
+ font-weight: 800;
+}
+
+.reward-info span {
+ font-size: 0.75rem;
+ color: #7f8c8d;
+}
+
+.celebration-actions {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+.btn-grand-celebration {
+ width: 100%;
+ padding: clamp(10px, 2vh, 15px);
+ border: none;
+ border-radius: 12px;
+ font-size: clamp(1rem, 2.2vh, 1.25rem);
+ font-weight: 800;
+ font-family: var(--font-main);
+ cursor: pointer;
+ transition: all 0.15s ease;
+}
+
+.btn-next-quest {
+ background: linear-gradient(180deg, #2ecc71 0%, #27ae60 100%);
+ color: white;
+ box-shadow: 0 4px 0 #1e8449, 0 8px 20px rgba(39, 174, 96, 0.4);
+ animation: pulse 1.2s infinite;
+}
+
+.btn-next-quest:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 6px 0 #1e8449, 0 12px 24px rgba(39, 174, 96, 0.5);
+}
+
+.secondary-actions-row {
+ display: flex;
+ gap: 8px;
+ width: 100%;
+}
+
+.btn-secondary-celebration {
+ flex: 1;
+ background: #fff;
+ border: 2px solid #bdc3c7;
+ border-radius: 10px;
+ padding: clamp(6px, 1.2vh, 10px);
+ font-size: clamp(0.8rem, 1.6vh, 0.95rem);
+ font-weight: 700;
+ font-family: var(--font-main);
+ color: #34495e;
+ cursor: pointer;
+ transition: all 0.15s ease;
+}
+
+.btn-secondary-celebration:hover {
+ background: #f4f6f7;
+ border-color: #7f8c8d;
+}
+
+/* Defeat Modal Styling */
+.defeat-header { margin-bottom: 8px; }
+.defeat-icon { font-size: clamp(2rem, 4.5vh, 2.8rem); display: block; }
+.defeat-title { margin: 2px 0; font-size: clamp(1.4rem, 3.2vh, 1.9rem); color: #c0392b; font-weight: 800; }
+.defeat-subtitle { color: #7f8c8d; font-size: clamp(0.8rem, 1.6vh, 0.95rem); margin: 0; }
+.defeat-encouragement {
+ font-size: clamp(0.85rem, 1.8vh, 1rem);
+ color: #2c3e50;
+ font-style: italic;
+ background: white;
+ padding: 10px 14px;
+ border-radius: 10px;
+ border: 1px dashed #e74c3c;
+ margin: 8px 0 14px 0;
+}
+
+.btn-retry-quest {
+ background: linear-gradient(180deg, #e74c3c 0%, #c0392b 100%);
+ color: white;
+ box-shadow: 0 4px 0 #922b21;
+}
+
+.btn-retry-quest:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 6px 0 #922b21;
+}
+
+/* ========================================================
+ FAIRYTALE LEVEL TRANSITION SCREEN (CLOUDS & MARCHING)
+ ======================================================== */
+.transition-screen-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+ background: rgba(26, 37, 47, 0.85);
+ backdrop-filter: blur(8px);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 10000;
+}
+
+.transition-parchment-box {
+ background: var(--color-parchment);
+ border: 4px solid var(--color-gold);
+ border-radius: 20px;
+ padding: clamp(20px, 4vh, 32px) clamp(24px, 4vw, 44px);
+ text-align: center;
+ box-shadow: 0 12px 36px rgba(0,0,0,0.5);
+ max-width: 440px;
+ width: 90%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.transition-hero-marching {
+ width: clamp(80px, 16vh, 120px);
+ height: clamp(80px, 16vh, 120px);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin-bottom: 6px;
+ position: relative;
+}
+
+.marching-hero-img {
+ max-height: 100%;
+ max-width: 100%;
+ object-fit: contain;
+ filter: drop-shadow(0 6px 12px rgba(0,0,0,0.3));
+}
+
+.transition-title {
+ font-size: clamp(1.2rem, 2.6vh, 1.5rem);
+ color: #8b5a2b;
+ margin: 4px 0 2px 0;
+ font-weight: 800;
+}
+
+.transition-target {
+ font-size: clamp(0.9rem, 1.8vh, 1.05rem);
+ color: #2c3e50;
+ font-weight: 700;
+ margin: 2px 0 10px 0;
+}
+
+.transition-sparkles {
+ display: flex;
+ gap: 12px;
+ font-size: 1.4rem;
+}
+
+.sparkle { animation: bounce 0.6s infinite alternate; }
+.sparkle:nth-child(2) { animation-delay: 0.2s; }
+.sparkle:nth-child(3) { animation-delay: 0.4s; }
+
+/* ANIMATION KEYFRAMES */
+@keyframes victoryModalPop {
+ 0% { transform: scale(0.7) translateY(20px); opacity: 0; }
+ 70% { transform: scale(1.05) translateY(-4px); opacity: 1; }
+ 100% { transform: scale(1) translateY(0); opacity: 1; }
+}
+
+.anim-victory-modal-pop {
+ animation: victoryModalPop 0.45s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
+}
+
+.anim-hero-victory {
+ animation: heroVictoryJump 1.2s infinite ease-in-out alternate;
+}
+
+@keyframes heroVictoryJump {
+ 0% { transform: translateY(0) scale(1); }
+ 50% { transform: translateY(-8px) scale(1.08) rotate(2deg); }
+ 100% { transform: translateY(0) scale(1); }
+}
+
+.anim-hero-march {
+ animation: heroMarchBob 0.6s infinite ease-in-out alternate;
+}
+
+@keyframes heroMarchBob {
+ 0% { transform: translateY(0) rotate(-2deg); }
+ 100% { transform: translateY(-6px) rotate(2deg); }
+}
+
+.anim-fade-in {
+ animation: fadeIn 0.3s ease-out forwards;
+}
-/* ANIMATIONS */
@keyframes bounce {
from { transform: translateY(0); }
to { transform: translateY(-4px); }
}
-@keyframes pulse {
- 0% { transform: scale(1); }
- 50% { transform: scale(1.08); }
- 100% { transform: scale(1); }
-}
-
-@keyframes fadeIn {
- from { opacity: 0; transform: translateY(-8px); }
- to { opacity: 1; transform: translateY(0); }
-}
-
.anim-hero-idle { animation: idleBreathe 3s infinite ease-in-out; }
.anim-enemy-idle { animation: idleBreathe 3s infinite ease-in-out 0.5s; }
.anim-hero-attack { animation: heroAttackDash 0.8s ease-out; }
diff --git a/src/CiselnaVyprava/wwwroot/data/worlds-grade1.json b/src/CiselnaVyprava/wwwroot/data/worlds-grade1.json
index 62684d0..5d7ac9d 100644
--- a/src/CiselnaVyprava/wwwroot/data/worlds-grade1.json
+++ b/src/CiselnaVyprava/wwwroot/data/worlds-grade1.json
@@ -2,54 +2,24 @@
{
"id": 1,
"grade": 1,
- "name": "Rozprávková lúka (Počítanie do 10)",
- "description": "Jednoduché sčítanie a odčítanie do 10 pre malých prváčikov.",
+ "name": "Svet 1: Rozprávková lúka (Do 10)",
+ "description": "Základné sčítanie a odčítanie v obore do 10 pre prváčikov.",
"background": "assets/images/backgrounds/world1_meadow.jpg",
"levels": [
{
"id": "1-1-1",
"levelNumber": 1,
"name": "Lúčny Motýlik",
- "enemy": {
- "id": "meadow_butterfly",
- "name": "Lúčny Motýlik",
- "maxHp": 20,
- "attackPower": 1,
- "assetFolder": "assets/images/enemies/goblin"
- },
- "mathConfig": {
- "operations": ["+"],
- "minA": 1,
- "maxA": 5,
- "minB": 1,
- "maxB": 5,
- "maxSum": 10,
- "allowCarryOver": false,
- "inputType": "DirectInput"
- },
+ "enemy": { "id": "meadow_butterfly", "name": "Lúčny Motýlik", "maxHp": 20, "attackPower": 1, "assetFolder": "assets/images/enemies/goblin" },
+ "mathConfig": { "operations": ["+"], "minA": 1, "maxA": 5, "minB": 1, "maxB": 5, "maxSum": 10, "allowCarryOver": false, "inputType": "DirectInput" },
"requiredCorrectAnswers": 3
},
{
"id": "1-1-2",
"levelNumber": 2,
"name": "Zvedavý Zajačik",
- "enemy": {
- "id": "curious_bunny",
- "name": "Zvedavý Zajačik",
- "maxHp": 25,
- "attackPower": 1,
- "assetFolder": "assets/images/enemies/slime"
- },
- "mathConfig": {
- "operations": ["+", "-"],
- "minA": 2,
- "maxA": 10,
- "minB": 1,
- "maxB": 5,
- "maxSum": 10,
- "allowCarryOver": false,
- "inputType": "DirectInput"
- },
+ "enemy": { "id": "curious_bunny", "name": "Zvedavý Zajačik", "maxHp": 25, "attackPower": 1, "assetFolder": "assets/images/enemies/slime" },
+ "mathConfig": { "operations": ["+", "-"], "minA": 2, "maxA": 10, "minB": 1, "maxB": 5, "maxSum": 10, "allowCarryOver": false, "inputType": "DirectInput" },
"requiredCorrectAnswers": 3
},
{
@@ -57,23 +27,8 @@
"levelNumber": 3,
"name": "Lesný Medveď (Boss)",
"isBoss": true,
- "enemy": {
- "id": "gentle_bear_boss",
- "name": "Strážca Lúky",
- "maxHp": 40,
- "attackPower": 1,
- "assetFolder": "assets/images/enemies/golem"
- },
- "mathConfig": {
- "operations": ["+", "-"],
- "minA": 3,
- "maxA": 10,
- "minB": 1,
- "maxB": 5,
- "maxSum": 10,
- "allowCarryOver": false,
- "inputType": "DirectInput"
- },
+ "enemy": { "id": "gentle_bear_boss", "name": "Strážca Lúky", "maxHp": 40, "attackPower": 1, "assetFolder": "assets/images/enemies/golem" },
+ "mathConfig": { "operations": ["+", "-"], "minA": 3, "maxA": 10, "minB": 1, "maxB": 5, "maxSum": 10, "allowCarryOver": false, "inputType": "DirectInput" },
"requiredCorrectAnswers": 4
}
]
@@ -81,32 +36,86 @@
{
"id": 2,
"grade": 1,
- "name": "Slnečná čistinka (Počítanie do 20 bez prechodu)",
- "description": "Sčítanie a odčítanie v obore do 20 (napr. 10 + 4, 15 - 3).",
+ "name": "Svet 2: Slnečná čistinka (Do 20 bez prechodu)",
+ "description": "Sčítanie a odčítanie v obore do 20 bez prechodu cez desiatku.",
"background": "assets/images/backgrounds/world2_forest.jpg",
"levels": [
{
"id": "1-2-1",
"levelNumber": 1,
"name": "Lesný Škriatok",
- "enemy": {
- "id": "forest_gnome",
- "name": "Lesný Škriatok",
- "maxHp": 30,
- "attackPower": 1,
- "assetFolder": "assets/images/enemies/goblin"
- },
- "mathConfig": {
- "operations": ["+", "-"],
- "minA": 10,
- "maxA": 19,
- "minB": 1,
- "maxB": 5,
- "maxSum": 20,
- "allowCarryOver": false,
- "inputType": "DirectInput"
- },
+ "enemy": { "id": "forest_gnome", "name": "Lesný Škriatok", "maxHp": 30, "attackPower": 1, "assetFolder": "assets/images/enemies/goblin" },
+ "mathConfig": { "operations": ["+", "-"], "minA": 10, "maxA": 19, "minB": 1, "maxB": 5, "maxSum": 20, "allowCarryOver": false, "inputType": "DirectInput" },
"requiredCorrectAnswers": 4
+ },
+ {
+ "id": "1-2-2",
+ "levelNumber": 2,
+ "name": "Kráľovský Ježko",
+ "enemy": { "id": "royal_hedgehog", "name": "Kráľovský Ježko", "maxHp": 35, "attackPower": 1, "assetFolder": "assets/images/enemies/slime" },
+ "mathConfig": { "operations": ["+", "-"], "minA": 11, "maxA": 19, "minB": 1, "maxB": 8, "maxSum": 20, "allowCarryOver": false, "inputType": "DirectInput" },
+ "requiredCorrectAnswers": 4
+ }
+ ]
+ },
+ {
+ "id": 3,
+ "grade": 1,
+ "name": "Svet 3: Zrkadlové jazierko (Porovnávanie < > =)",
+ "description": "Zisťovanie, ktoré číslo je väčšie, menšie alebo rovnaké.",
+ "background": "assets/images/backgrounds/world3_river.jpg",
+ "levels": [
+ {
+ "id": "1-3-1",
+ "levelNumber": 1,
+ "name": "Vodná Víla",
+ "enemy": { "id": "water_fairy", "name": "Vodná Víla", "maxHp": 30, "attackPower": 1, "assetFolder": "assets/images/enemies/goblin" },
+ "mathConfig": { "operations": ["<", ">", "="], "minA": 1, "maxA": 20, "minB": 1, "maxB": 20, "inputType": "MultipleChoice" },
+ "requiredCorrectAnswers": 4
+ },
+ {
+ "id": "1-3-2",
+ "levelNumber": 2,
+ "name": "Riečny Had (Boss)",
+ "isBoss": true,
+ "enemy": { "id": "river_serpent_boss", "name": "Riečny Had", "maxHp": 50, "attackPower": 1, "assetFolder": "assets/images/enemies/golem" },
+ "mathConfig": { "operations": ["<", ">", "="], "minA": 5, "maxA": 20, "minB": 5, "maxB": 20, "inputType": "MultipleChoice" },
+ "requiredCorrectAnswers": 5
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "grade": 1,
+ "name": "Svet 4: Horská pevnosť (Desiatky)",
+ "description": "Počítanie po desiatkach do 100 (10, 20, 30...).",
+ "background": "assets/images/backgrounds/world1_meadow.jpg",
+ "levels": [
+ {
+ "id": "1-4-1",
+ "levelNumber": 1,
+ "name": "Kamenný Strážca",
+ "enemy": { "id": "stone_watcher", "name": "Kamenný Strážca", "maxHp": 35, "attackPower": 1, "assetFolder": "assets/images/enemies/golem" },
+ "mathConfig": { "operations": ["+", "-"], "minA": 10, "maxA": 50, "minB": 10, "maxB": 40, "maxSum": 100, "allowCarryOver": false, "inputType": "DirectInput" },
+ "requiredCorrectAnswers": 4
+ }
+ ]
+ },
+ {
+ "id": 5,
+ "grade": 1,
+ "name": "Svet 5: Kráľovský Hrad (Finále 1. ročníka)",
+ "description": "Veľký záverečný test všetkých zručností prvého ročníka!",
+ "background": "assets/images/backgrounds/title_screen_bg.jpg",
+ "levels": [
+ {
+ "id": "1-5-1",
+ "levelNumber": 1,
+ "name": "Kráľovský Drak (Veľký Boss)",
+ "isBoss": true,
+ "enemy": { "id": "king_dragon_boss", "name": "Kráľovský Drak", "maxHp": 60, "attackPower": 1, "assetFolder": "assets/images/enemies/golem" },
+ "mathConfig": { "operations": ["+", "-"], "minA": 5, "maxA": 20, "minB": 1, "maxB": 10, "maxSum": 20, "allowCarryOver": false, "inputType": "DirectInput" },
+ "requiredCorrectAnswers": 6
}
]
}
diff --git a/src/CiselnaVyprava/wwwroot/data/worlds-grade2.json b/src/CiselnaVyprava/wwwroot/data/worlds-grade2.json
index 306c0ae..5cebdc1 100644
--- a/src/CiselnaVyprava/wwwroot/data/worlds-grade2.json
+++ b/src/CiselnaVyprava/wwwroot/data/worlds-grade2.json
@@ -2,7 +2,7 @@
{
"id": 1,
"grade": 2,
- "name": "Lúka sčítania a odčítania",
+ "name": "Svet 1: Lúka sčítania a odčítania (Do 20 s prechodom)",
"description": "Základné sčítanie a odčítanie do 20 s prechodom cez desiatku.",
"background": "assets/images/backgrounds/world1_meadow.jpg",
"levels": [
@@ -19,10 +19,10 @@
},
"mathConfig": {
"operations": ["+"],
- "minA": 1,
- "maxA": 10,
- "minB": 1,
- "maxB": 10,
+ "minA": 2,
+ "maxA": 9,
+ "minB": 2,
+ "maxB": 9,
"maxSum": 20,
"allowCarryOver": true,
"inputType": "DirectInput"
@@ -43,9 +43,9 @@
"mathConfig": {
"operations": ["+", "-"],
"minA": 5,
- "maxA": 20,
- "minB": 1,
- "maxB": 10,
+ "maxA": 18,
+ "minB": 2,
+ "maxB": 9,
"maxSum": 20,
"allowCarryOver": true,
"inputType": "DirectInput"
@@ -55,21 +55,21 @@
{
"id": "2-1-3",
"levelNumber": 3,
- "name": "Kamenný Golem (Boss)",
+ "name": "Golem Čísel (Boss)",
"isBoss": true,
"enemy": {
"id": "stone_golem_boss",
- "name": "Golem Čísiel",
+ "name": "Golem Čísel",
"maxHp": 60,
"attackPower": 1,
"assetFolder": "assets/images/enemies/golem"
},
"mathConfig": {
"operations": ["+", "-"],
- "minA": 8,
+ "minA": 6,
"maxA": 20,
- "minB": 4,
- "maxB": 10,
+ "minB": 3,
+ "maxB": 9,
"maxSum": 20,
"allowCarryOver": true,
"inputType": "DirectInput"
@@ -81,20 +81,63 @@
{
"id": 2,
"grade": 2,
- "name": "Les porovnávania a rovností",
- "description": "Porovnávanie čísel pomocou znakov <, >, = a dopĺňanie do desiatky.",
+ "name": "Svet 2: Les porovnávania (Do 100)",
+ "description": "Porovnávanie čísel pomocou znakov <, >, = v obore do 100.",
"background": "assets/images/backgrounds/world2_forest.jpg",
"levels": [
{
"id": "2-2-1",
"levelNumber": 1,
- "name": "Múdra Sova",
+ "name": "Lesný Goblin",
"enemy": {
- "id": "wise_owl",
- "name": "Múdra Sova",
- "maxHp": 30,
+ "id": "forest_goblin_comp",
+ "name": "Lesný Goblin",
+ "maxHp": 35,
"attackPower": 1,
- "assetFolder": "assets/images/enemies/owl"
+ "assetFolder": "assets/images/enemies/goblin"
+ },
+ "mathConfig": {
+ "operations": ["<", ">", "="],
+ "minA": 1,
+ "maxA": 50,
+ "minB": 1,
+ "maxB": 50,
+ "inputType": "MultipleChoice"
+ },
+ "requiredCorrectAnswers": 4
+ },
+ {
+ "id": "2-2-2",
+ "levelNumber": 2,
+ "name": "Slizký Strážca",
+ "enemy": {
+ "id": "slime_comp_watcher",
+ "name": "Slizký Strážca",
+ "maxHp": 40,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/slime"
+ },
+ "mathConfig": {
+ "operations": ["<", ">", "="],
+ "minA": 20,
+ "maxA": 100,
+ "minB": 20,
+ "maxB": 100,
+ "inputType": "MultipleChoice"
+ },
+ "requiredCorrectAnswers": 4
+ },
+ {
+ "id": "2-2-3",
+ "levelNumber": 3,
+ "name": "Strážca Hvozdu (Boss)",
+ "isBoss": true,
+ "enemy": {
+ "id": "forest_golem_comp_boss",
+ "name": "Strážca Hvozdu",
+ "maxHp": 55,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/golem"
},
"mathConfig": {
"operations": ["<", ">", "="],
@@ -104,7 +147,235 @@
"maxB": 100,
"inputType": "MultipleChoice"
},
+ "requiredCorrectAnswers": 5
+ }
+ ]
+ },
+ {
+ "id": 3,
+ "grade": 2,
+ "name": "Svet 3: Riečna zátoka (Do 100 bez prechodu)",
+ "description": "Sčítanie a odčítanie desiatok a dvojciferných čísel bez prechodu.",
+ "background": "assets/images/backgrounds/world3_river.jpg",
+ "levels": [
+ {
+ "id": "2-3-1",
+ "levelNumber": 1,
+ "name": "Riečny Goblin",
+ "enemy": {
+ "id": "river_goblin_easy",
+ "name": "Riečny Goblin",
+ "maxHp": 35,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/goblin"
+ },
+ "mathConfig": {
+ "operations": ["+", "-"],
+ "minA": 10,
+ "maxA": 80,
+ "minB": 1,
+ "maxB": 9,
+ "maxSum": 100,
+ "allowCarryOver": false,
+ "inputType": "DirectInput"
+ },
"requiredCorrectAnswers": 4
+ },
+ {
+ "id": "2-3-2",
+ "levelNumber": 2,
+ "name": "Kvapkový Sliz",
+ "enemy": {
+ "id": "droplet_slime",
+ "name": "Kvapkový Sliz",
+ "maxHp": 45,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/slime"
+ },
+ "mathConfig": {
+ "operations": ["+", "-"],
+ "minA": 20,
+ "maxA": 70,
+ "minB": 10,
+ "maxB": 25,
+ "maxSum": 100,
+ "allowCarryOver": false,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 4
+ },
+ {
+ "id": "2-3-3",
+ "levelNumber": 3,
+ "name": "Balvanový Netvor (Boss)",
+ "isBoss": true,
+ "enemy": {
+ "id": "river_golem_boss",
+ "name": "Balvanový Netvor",
+ "maxHp": 65,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/golem"
+ },
+ "mathConfig": {
+ "operations": ["+", "-"],
+ "minA": 20,
+ "maxA": 90,
+ "minB": 5,
+ "maxB": 30,
+ "maxSum": 100,
+ "allowCarryOver": false,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 5
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "grade": 2,
+ "name": "Svet 4: Horský priesmyk (Do 100 s prechodom)",
+ "description": "Sčítanie a odčítanie s prechodom cez desiatku v obore do 100.",
+ "background": "assets/images/backgrounds/world1_meadow.jpg",
+ "levels": [
+ {
+ "id": "2-4-1",
+ "levelNumber": 1,
+ "name": "Horský Goblin",
+ "enemy": {
+ "id": "mountain_goblin",
+ "name": "Horský Goblin",
+ "maxHp": 40,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/goblin"
+ },
+ "mathConfig": {
+ "operations": ["+", "-"],
+ "minA": 15,
+ "maxA": 75,
+ "minB": 4,
+ "maxB": 9,
+ "maxSum": 100,
+ "allowCarryOver": true,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 4
+ },
+ {
+ "id": "2-4-2",
+ "levelNumber": 2,
+ "name": "Magický Horský Sliz",
+ "enemy": {
+ "id": "mountain_magic_slime",
+ "name": "Magický Horský Sliz",
+ "maxHp": 50,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/slime"
+ },
+ "mathConfig": {
+ "operations": ["+", "-"],
+ "minA": 20,
+ "maxA": 85,
+ "minB": 6,
+ "maxB": 15,
+ "maxSum": 100,
+ "allowCarryOver": true,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 5
+ },
+ {
+ "id": "2-4-3",
+ "levelNumber": 3,
+ "name": "Horský Obor (Boss)",
+ "isBoss": true,
+ "enemy": {
+ "id": "mountain_giant_boss",
+ "name": "Horský Obor",
+ "maxHp": 70,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/golem"
+ },
+ "mathConfig": {
+ "operations": ["+", "-"],
+ "minA": 25,
+ "maxA": 90,
+ "minB": 8,
+ "maxB": 25,
+ "maxSum": 100,
+ "allowCarryOver": true,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 5
+ }
+ ]
+ },
+ {
+ "id": 5,
+ "grade": 2,
+ "name": "Svet 5: Hrad malej násobilky (Úvod do násobenia)",
+ "description": "Základy násobenia číslami 2, 3, 5 a 10.",
+ "background": "assets/images/backgrounds/title_screen_bg.jpg",
+ "levels": [
+ {
+ "id": "2-5-1",
+ "levelNumber": 1,
+ "name": "Hradný Strážca",
+ "enemy": {
+ "id": "castle_guard_goblin",
+ "name": "Hradný Strážca",
+ "maxHp": 40,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/goblin"
+ },
+ "mathConfig": {
+ "operations": ["*"],
+ "factors": [2, 5],
+ "minMultiplier": 1,
+ "maxMultiplier": 10,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 4
+ },
+ {
+ "id": "2-5-2",
+ "levelNumber": 2,
+ "name": "Kráľovský Sliz",
+ "enemy": {
+ "id": "royal_castle_slime",
+ "name": "Kráľovský Sliz",
+ "maxHp": 50,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/slime"
+ },
+ "mathConfig": {
+ "operations": ["*"],
+ "factors": [2, 3, 5, 10],
+ "minMultiplier": 1,
+ "maxMultiplier": 10,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 5
+ },
+ {
+ "id": "2-5-3",
+ "levelNumber": 3,
+ "name": "Veľký Hradný Pán (Finále 2. ročníka)",
+ "isBoss": true,
+ "enemy": {
+ "id": "castle_lord_boss",
+ "name": "Veľký Hradný Pán",
+ "maxHp": 75,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/golem"
+ },
+ "mathConfig": {
+ "operations": ["*"],
+ "factors": [2, 3, 5, 10],
+ "minMultiplier": 1,
+ "maxMultiplier": 10,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 6
}
]
}
diff --git a/src/CiselnaVyprava/wwwroot/data/worlds-grade3.json b/src/CiselnaVyprava/wwwroot/data/worlds-grade3.json
index 23b572e..96bf14f 100644
--- a/src/CiselnaVyprava/wwwroot/data/worlds-grade3.json
+++ b/src/CiselnaVyprava/wwwroot/data/worlds-grade3.json
@@ -2,8 +2,8 @@
{
"id": 1,
"grade": 3,
- "name": "Rieka malej násobilky (2, 3, 4, 5)",
- "description": "Základy násobenia a delenia číslami 2, 3, 4, 5.",
+ "name": "Svet 1: Rieka malej násobilky (2, 3, 4, 5)",
+ "description": "Základy násobenia a delenia číslami 2, 3, 4 a 5.",
"background": "assets/images/backgrounds/world3_river.jpg",
"levels": [
{
@@ -11,11 +11,11 @@
"levelNumber": 1,
"name": "Riečny Škriatok",
"enemy": {
- "id": "river_sprite",
+ "id": "river_sprite_goblin",
"name": "Riečny Škriatok",
- "maxHp": 30,
+ "maxHp": 35,
"attackPower": 1,
- "assetFolder": "assets/images/enemies/sprite"
+ "assetFolder": "assets/images/enemies/goblin"
},
"mathConfig": {
"operations": ["*"],
@@ -29,13 +29,34 @@
{
"id": "3-1-2",
"levelNumber": 2,
- "name": "Vodník Násobka",
+ "name": "Vodný Slizík",
"enemy": {
- "id": "water_demon",
- "name": "Vodník Násobka",
- "maxHp": 40,
+ "id": "water_slime_div",
+ "name": "Vodný Slizík",
+ "maxHp": 45,
"attackPower": 1,
- "assetFolder": "assets/images/enemies/water_demon"
+ "assetFolder": "assets/images/enemies/slime"
+ },
+ "mathConfig": {
+ "operations": ["/"],
+ "factors": [2, 3, 4, 5],
+ "minMultiplier": 1,
+ "maxMultiplier": 10,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 4
+ },
+ {
+ "id": "3-1-3",
+ "levelNumber": 3,
+ "name": "Jazerný Strážca (Boss)",
+ "isBoss": true,
+ "enemy": {
+ "id": "lake_golem_boss",
+ "name": "Jazerný Strážca",
+ "maxHp": 65,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/golem"
},
"mathConfig": {
"operations": ["*", "/"],
@@ -45,22 +66,71 @@
"inputType": "DirectInput"
},
"requiredCorrectAnswers": 5
+ }
+ ]
+ },
+ {
+ "id": 2,
+ "grade": 3,
+ "name": "Svet 2: Les veľkej násobilky (6, 7, 8, 9, 10)",
+ "description": "Násobenie a delenie vyššími číslami 6 až 10.",
+ "background": "assets/images/backgrounds/world2_forest.jpg",
+ "levels": [
+ {
+ "id": "3-2-1",
+ "levelNumber": 1,
+ "name": "Lesný Piadimužík",
+ "enemy": {
+ "id": "forest_dwarf_goblin",
+ "name": "Lesný Piadimužík",
+ "maxHp": 40,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/goblin"
+ },
+ "mathConfig": {
+ "operations": ["*"],
+ "factors": [6, 7, 8, 9, 10],
+ "minMultiplier": 1,
+ "maxMultiplier": 10,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 4
},
{
- "id": "3-1-3",
+ "id": "3-2-2",
+ "levelNumber": 2,
+ "name": "Živicový Sliz",
+ "enemy": {
+ "id": "resin_slime_div",
+ "name": "Živicový Sliz",
+ "maxHp": 50,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/slime"
+ },
+ "mathConfig": {
+ "operations": ["/"],
+ "factors": [6, 7, 8, 9, 10],
+ "minMultiplier": 1,
+ "maxMultiplier": 10,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 5
+ },
+ {
+ "id": "3-2-3",
"levelNumber": 3,
- "name": "Jazerný Drak (Boss)",
+ "name": "Starý Lesný Golem (Boss)",
"isBoss": true,
"enemy": {
- "id": "lake_dragon_boss",
- "name": "Jazerný Drak",
- "maxHp": 60,
+ "id": "ancient_forest_golem_boss",
+ "name": "Starý Lesný Golem",
+ "maxHp": 70,
"attackPower": 1,
- "assetFolder": "assets/images/enemies/dragon"
+ "assetFolder": "assets/images/enemies/golem"
},
"mathConfig": {
"operations": ["*", "/"],
- "factors": [2, 3, 4, 5],
+ "factors": [6, 7, 8, 9, 10],
"minMultiplier": 1,
"maxMultiplier": 10,
"inputType": "DirectInput"
@@ -68,5 +138,237 @@
"requiredCorrectAnswers": 6
}
]
+ },
+ {
+ "id": 3,
+ "grade": 3,
+ "name": "Svet 3: Krištáľové údolie (Počítanie do 1000)",
+ "description": "Sčítanie a odčítanie v obore do 1000 po stovkách a desiatkach.",
+ "background": "assets/images/backgrounds/world1_meadow.jpg",
+ "levels": [
+ {
+ "id": "3-3-1",
+ "levelNumber": 1,
+ "name": "Jaskynný Goblin",
+ "enemy": {
+ "id": "cave_goblin_1000",
+ "name": "Jaskynný Goblin",
+ "maxHp": 45,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/goblin"
+ },
+ "mathConfig": {
+ "operations": ["+", "-"],
+ "minA": 100,
+ "maxA": 800,
+ "minB": 50,
+ "maxB": 200,
+ "maxSum": 1000,
+ "allowCarryOver": false,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 4
+ },
+ {
+ "id": "3-3-2",
+ "levelNumber": 2,
+ "name": "Trblietavý Sliz",
+ "enemy": {
+ "id": "glitter_slime_1000",
+ "name": "Trblietavý Sliz",
+ "maxHp": 55,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/slime"
+ },
+ "mathConfig": {
+ "operations": ["+", "-"],
+ "minA": 200,
+ "maxA": 900,
+ "minB": 100,
+ "maxB": 300,
+ "maxSum": 1000,
+ "allowCarryOver": true,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 5
+ },
+ {
+ "id": "3-3-3",
+ "levelNumber": 3,
+ "name": "Kryštálový Golem (Boss)",
+ "isBoss": true,
+ "enemy": {
+ "id": "crystal_golem_boss",
+ "name": "Kryštálový Golem",
+ "maxHp": 75,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/golem"
+ },
+ "mathConfig": {
+ "operations": ["+", "-"],
+ "minA": 150,
+ "maxA": 850,
+ "minB": 50,
+ "maxB": 350,
+ "maxSum": 1000,
+ "allowCarryOver": true,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 6
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "grade": 3,
+ "name": "Svet 4: Veterné bralo (Porovnávanie do 1000)",
+ "description": "Porovnávanie veľkých trojciferných čísel pomocou znakov <, >, =.",
+ "background": "assets/images/backgrounds/world3_river.jpg",
+ "levels": [
+ {
+ "id": "3-4-1",
+ "levelNumber": 1,
+ "name": "Veterný Škriatok",
+ "enemy": {
+ "id": "wind_sprite_goblin",
+ "name": "Veterný Škriatok",
+ "maxHp": 40,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/goblin"
+ },
+ "mathConfig": {
+ "operations": ["<", ">", "="],
+ "minA": 100,
+ "maxA": 999,
+ "minB": 100,
+ "maxB": 999,
+ "inputType": "MultipleChoice"
+ },
+ "requiredCorrectAnswers": 4
+ },
+ {
+ "id": "3-4-2",
+ "levelNumber": 2,
+ "name": "Búrkový Sliz",
+ "enemy": {
+ "id": "storm_slime_comp",
+ "name": "Búrkový Sliz",
+ "maxHp": 50,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/slime"
+ },
+ "mathConfig": {
+ "operations": ["<", ">", "="],
+ "minA": 300,
+ "maxA": 1000,
+ "minB": 300,
+ "maxB": 1000,
+ "inputType": "MultipleChoice"
+ },
+ "requiredCorrectAnswers": 5
+ },
+ {
+ "id": "3-4-3",
+ "levelNumber": 3,
+ "name": "Hromový Golem (Boss)",
+ "isBoss": true,
+ "enemy": {
+ "id": "thunder_golem_boss",
+ "name": "Hromový Golem",
+ "maxHp": 75,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/golem"
+ },
+ "mathConfig": {
+ "operations": ["<", ">", "="],
+ "minA": 100,
+ "maxA": 1000,
+ "minB": 100,
+ "maxB": 1000,
+ "inputType": "MultipleChoice"
+ },
+ "requiredCorrectAnswers": 6
+ }
+ ]
+ },
+ {
+ "id": 5,
+ "grade": 3,
+ "name": "Svet 5: Kráľovská citadela (Veľké finále)",
+ "description": "Záverečná výzva tretieho ročníka – mix násobilky, delenia a veľkých čísel!",
+ "background": "assets/images/backgrounds/title_screen_bg.jpg",
+ "levels": [
+ {
+ "id": "3-5-1",
+ "levelNumber": 1,
+ "name": "Elitný Goblin",
+ "enemy": {
+ "id": "elite_guard_goblin",
+ "name": "Elitný Goblin",
+ "maxHp": 50,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/goblin"
+ },
+ "mathConfig": {
+ "operations": ["*", "/"],
+ "factors": [2, 3, 4, 5, 6, 7, 8, 9, 10],
+ "minMultiplier": 1,
+ "maxMultiplier": 10,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 5
+ },
+ {
+ "id": "3-5-2",
+ "levelNumber": 2,
+ "name": "Magický Plazmový Sliz",
+ "enemy": {
+ "id": "plasma_slime_boss",
+ "name": "Magický Plazmový Sliz",
+ "maxHp": 65,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/slime"
+ },
+ "mathConfig": {
+ "operations": ["+", "-", "*", "/"],
+ "minA": 10,
+ "maxA": 100,
+ "minB": 5,
+ "maxB": 50,
+ "maxSum": 200,
+ "factors": [2, 3, 4, 5, 6, 7, 8, 9, 10],
+ "minMultiplier": 1,
+ "maxMultiplier": 10,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 6
+ },
+ {
+ "id": "3-5-3",
+ "levelNumber": 3,
+ "name": "Arcimág Čísel (Záverečný Boss)",
+ "isBoss": true,
+ "enemy": {
+ "id": "archmage_golem_final_boss",
+ "name": "Arcimág Čísel",
+ "maxHp": 85,
+ "attackPower": 1,
+ "assetFolder": "assets/images/enemies/golem"
+ },
+ "mathConfig": {
+ "operations": ["+", "-", "*", "/"],
+ "minA": 10,
+ "maxA": 500,
+ "minB": 10,
+ "maxB": 200,
+ "maxSum": 1000,
+ "factors": [2, 3, 4, 5, 6, 7, 8, 9, 10],
+ "minMultiplier": 1,
+ "maxMultiplier": 10,
+ "inputType": "DirectInput"
+ },
+ "requiredCorrectAnswers": 8
+ }
+ ]
}
]
diff --git a/src/CiselnaVyprava/wwwroot/index.html b/src/CiselnaVyprava/wwwroot/index.html
index d17b325..6894b43 100644
--- a/src/CiselnaVyprava/wwwroot/index.html
+++ b/src/CiselnaVyprava/wwwroot/index.html
@@ -13,8 +13,6 @@
-
-
@@ -38,8 +36,9 @@
Obnoviť hru
🗙