diff --git a/lessons/00-welcome.json b/lessons/00-welcome.json
new file mode 100644
index 0000000..fe5aa92
--- /dev/null
+++ b/lessons/00-welcome.json
@@ -0,0 +1,111 @@
+{
+ "$schema": "../schemas/code-crispies-module-schema.json",
+ "id": "welcome",
+ "title": "Welcome",
+ "description": "Learn how to use Code Crispies and get started with interactive web development lessons",
+ "mode": "html",
+ "difficulty": "beginner",
+ "lessons": [
+ {
+ "id": "what-is-code-crispies",
+ "title": "What is Code Crispies?",
+ "description": "Code Crispies is a free, open-source platform for learning web development through hands-on exercises.
You'll learn:
- HTML - Semantic markup and native elements
- CSS - Styling and layout techniques
- Tailwind - Utility-first CSS framework
No account required - just start coding!",
+ "task": "Try it out! Type <h1>Hello World</h1> in the editor below and watch the preview update.",
+ "previewHTML": "",
+ "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 20px; text-align: center; } h1 { color: #6366f1; }",
+ "sandboxCSS": "",
+ "initialCode": "",
+ "solution": "
I am learning!
", + "previewContainer": "preview-area", + "validations": [ + { + "type": "element_exists", + "value": "p", + "message": "Add a <p> paragraph element" + }, + { + "type": "contains", + "value": "learning", + "message": "Include the word 'learning' in your paragraph" + } + ] + }, + { + "id": "navigation-tips", + "title": "Navigation Tips", + "description": "Use these controls to navigate:Let's start learning.
", + "previewContainer": "preview-area", + "validations": [ + { + "type": "element_exists", + "value": "h2", + "message": "Add an <h2> heading" + }, + { + "type": "element_exists", + "value": "p", + "message": "Add a <p> paragraph" + }, + { + "type": "contains", + "value": "Ready", + "message": "Include 'Ready!' in your heading" + } + ] + } + ] +} diff --git a/lessons/de/00-welcome.json b/lessons/de/00-welcome.json new file mode 100644 index 0000000..a1a7329 --- /dev/null +++ b/lessons/de/00-welcome.json @@ -0,0 +1,111 @@ +{ + "$schema": "../../schemas/code-crispies-module-schema.json", + "id": "welcome", + "title": "Willkommen", + "description": "Lerne, wie du Code Crispies nutzt und starte mit interaktiven Webentwicklungs-Lektionen", + "mode": "html", + "difficulty": "beginner", + "lessons": [ + { + "id": "what-is-code-crispies", + "title": "Was ist Code Crispies?", + "description": "Code Crispies ist eine kostenlose Open-Source-Plattform zum Erlernen von Webentwicklung durch praktische Übungen.Ich lerne!
", + "previewContainer": "preview-area", + "validations": [ + { + "type": "element_exists", + "value": "p", + "message": "Füge ein <p> Absatz-Element hinzu" + }, + { + "type": "contains", + "value": "lerne", + "message": "Füge das Wort 'lerne' in deinen Absatz ein" + } + ] + }, + { + "id": "navigation-tips", + "title": "Navigations-Tipps", + "description": "Nutze diese Steuerungen zur Navigation:Los geht's!
", + "previewContainer": "preview-area", + "validations": [ + { + "type": "element_exists", + "value": "h2", + "message": "Füge eine <h2> Überschrift hinzu" + }, + { + "type": "element_exists", + "value": "p", + "message": "Füge einen <p> Absatz hinzu" + }, + { + "type": "contains", + "value": "Fertig", + "message": "Füge 'Fertig!' in deine Überschrift ein" + } + ] + } + ] +} diff --git a/src/app.js b/src/app.js index dd22fd0..00214dd 100644 --- a/src/app.js +++ b/src/app.js @@ -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(); diff --git a/src/config/lessons.js b/src/config/lessons.js index 8d46814..f019d7e 100644 --- a/src/config/lessons.js +++ b/src/config/lessons.js @@ -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, diff --git a/src/main.css b/src/main.css index 75e7824..2e186ee 100644 --- a/src/main.css +++ b/src/main.css @@ -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);