feat: add welcome lesson, DVD bounce animation, mobile layout reorder

- Add Welcome module with intro lessons (EN/DE)
- Success message now bounces like DVD screensaver (10s duration)
- Mobile: nav bar at top, preview before editor
- Logo: CODE with purple background pill
This commit is contained in:
2025-12-30 21:44:37 +01:00
parent 7f3451922a
commit e28f23d126
5 changed files with 270 additions and 26 deletions

View File

@@ -599,11 +599,11 @@ function runCode() {
elements.nextBtn.classList.add("success");
elements.taskInstruction.classList.add("success-instruction");
// Show match animation
// Show match animation (DVD-style bouncing)
elements.previewWrapper?.classList.add("matched");
setTimeout(() => {
elements.previewWrapper?.classList.remove("matched");
}, 2500);
}, 10000);
updateNavigationButtons();
updateProgressDisplay();

View File

@@ -4,6 +4,7 @@
*/
// English lesson imports
import welcomeEN from "../../lessons/00-welcome.json";
import basicSelectorsEN from "../../lessons/00-basic-selectors.json";
import boxModelEN from "../../lessons/01-box-model.json";
import unitsVariablesEN from "../../lessons/05-units-variables.json";
@@ -20,6 +21,7 @@ import htmlSvgEN from "../../lessons/32-html-svg.json";
import flexboxEN from "../../lessons/flexbox.json";
// German lesson imports
import welcomeDE from "../../lessons/de/00-welcome.json";
import basicSelectorsDE from "../../lessons/de/00-basic-selectors.json";
import boxModelDE from "../../lessons/de/01-box-model.json";
import unitsVariablesDE from "../../lessons/de/05-units-variables.json";
@@ -37,6 +39,8 @@ import flexboxDE from "../../lessons/de/flexbox.json";
// English module store - ordered by learning path
const moduleStoreEN = [
// Welcome
welcomeEN,
// HTML Grundlagen
htmlElementsEN,
htmlFormsBasicEN,
@@ -61,6 +65,8 @@ const moduleStoreEN = [
// German module store - ordered by learning path
const moduleStoreDE = [
// Welcome
welcomeDE,
// HTML Grundlagen
htmlElementsDE,
htmlFormsBasicDE,

View File

@@ -589,27 +589,42 @@ code, kbd {
.preview-wrapper.matched::after {
content: "CRISPY! ٩(◕‿◕)۶";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: var(--success-color);
color: white;
padding: var(--spacing-sm) var(--spacing-lg);
border-radius: var(--border-radius-lg);
font-weight: bold;
font-size: 1.1rem;
animation: pop-in 0.4s ease-out;
animation: dvd-bounce 8s ease-in-out infinite;
z-index: 10;
white-space: nowrap;
}
@keyframes pop-in {
@keyframes dvd-bounce {
0% {
transform: translate(-50%, -50%) scale(0.8);
opacity: 0;
top: 10%;
left: 10%;
transform: scale(1);
}
25% {
top: 70%;
left: 80%;
transform: scale(1.1);
}
50% {
top: 20%;
left: 70%;
transform: scale(0.95);
}
75% {
top: 60%;
left: 15%;
transform: scale(1.05);
}
100% {
transform: translate(-50%, -50%) scale(1);
opacity: 1;
top: 10%;
left: 10%;
transform: scale(1);
}
}
@@ -1111,40 +1126,41 @@ input:checked + .toggle-slider::before {
width: 100%;
flex-shrink: 0;
border-right: none;
display: contents;
}
.left-panel {
min-height: 80vh;
border-bottom: 1px solid var(--border-color);
}
.right-panel {
min-height: 50vh;
/* Mobile order: nav -> instructions -> preview -> editor */
.game-controls {
order: 1;
padding: var(--spacing-sm);
}
.instructions {
order: 2;
max-height: none;
overflow-y: visible;
}
.preview-section {
order: 3;
}
.editor-section {
order: 4;
flex: 1;
min-height: 50vh;
}
.preview-wrapper {
margin: var(--spacing-sm);
min-height: 40vh;
}
.editor-content {
flex: 1;
min-height: 45vh;
}
.preview-wrapper {
margin: var(--spacing-sm);
}
.game-controls {
padding: var(--spacing-sm);
}
.module-pill {
flex: 1;
margin: 0 var(--spacing-sm);