feat: hide Run button, update LibreTECH branding, improve welcome lessons

- Hide Run button (live preview is stable)
- Update all references from librete.ch to LibreTECH
- Add context to repo links (Gitea Source, GitHub Mirror)
- Fix welcome lesson redundant text
- Slow down CRISPY animation to 8s
- Remove editor-tools margin-right
This commit is contained in:
2025-12-30 22:22:00 +01:00
parent 4928223291
commit 6303358521
7 changed files with 109 additions and 44 deletions

View File

@@ -27,20 +27,20 @@
},
{
"id": "get-started",
"title": "Get Started!",
"description": "<strong>You're ready!</strong> Open the menu (☰) to explore all modules.<br><br><strong>Recommended learning path:</strong><br>1. <em>HTML Block & Inline</em> - Understand container vs inline elements<br>2. <em>HTML Forms</em> - Build interactive forms with validation<br>3. <em>CSS Selectors</em> - Target elements precisely<br>4. <em>CSS Box Model</em> - Master padding, margin, borders<br>5. <em>CSS Flexbox</em> - Create flexible layouts<br>6. <em>CSS Animations</em> - Add motion and transitions<br><br><strong>Tips:</strong><br>• Use <em>Show Expected</em> to see the target result<br>• Your progress is saved automatically<br>• Try Emmet in HTML mode: <kbd>ul>li*3</kbd> + Tab<br><br><strong>Open Source:</strong><br>• <a href=\"https://github.com/nextlevelshit/code-crispies\" target=\"_blank\">GitHub</a> · <a href=\"https://git.librete.ch/libretech/code-crispies\" target=\"_blank\">Gitea</a><br>• Made by <a href=\"https://librete.ch\" target=\"_blank\">librete.ch</a> · <a href=\"https://www.linkedin.com/in/michael-werner-czechowski\" target=\"_blank\">LinkedIn</a>",
"task": "Let's go!",
"previewHTML": "<p>Hello World! 🌍</p><p>Hallo Welt!</p><p>Bonjour le monde!</p><p>¡Hola Mundo!</p><p>Ciao Mondo!</p><p>こんにちは世界!</p><p>Привет мир!</p><p dir=\"rtl\">مرحبا بالعالم!</p>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 16px; } p { margin: 8px 0; padding: 8px 16px; border-radius: 8px; font-weight: 600; } p:nth-child(1) { background: #fef3c7; color: #92400e; font-size: 1.4em; } p:nth-child(2) { background: #dcfce7; color: #166534; font-size: 1.2em; } p:nth-child(3) { background: #dbeafe; color: #1e40af; font-size: 1.1em; } p:nth-child(4) { background: #fce7f3; color: #9d174d; } p:nth-child(5) { background: #e0e7ff; color: #4338ca; font-size: 1.3em; } p:nth-child(6) { background: #fef9c3; color: #854d0e; } p:nth-child(7) { background: #fee2e2; color: #991b1b; font-size: 1.1em; } p:nth-child(8) { background: #f3e8ff; color: #7c3aed; }",
"title": "Good Luck!",
"description": "<strong>You're ready!</strong> Open the menu (☰) to explore all modules.<br><br><strong>Recommended learning path:</strong><br>1. <em>HTML Block & Inline</em> - Understand container vs inline elements<br>2. <em>HTML Forms</em> - Build interactive forms with validation<br>3. <em>CSS Selectors</em> - Target elements precisely<br>4. <em>CSS Box Model</em> - Master padding, margin, borders<br>5. <em>CSS Flexbox</em> - Create flexible layouts<br>6. <em>CSS Animations</em> - Add motion and transitions<br><br><strong>Tips:</strong><br>• Use <em>Show Expected</em> to see the target result<br>• Your progress is saved automatically<br>• Try Emmet in HTML mode: <kbd>ul>li*3</kbd> + Tab<br><br><strong>Open Source:</strong><br>• <a href=\"https://git.librete.ch/libretech/code-crispies\" target=\"_blank\">Gitea (Source)</a> · <a href=\"https://github.com/nextlevelshit/code-crispies\" target=\"_blank\">GitHub (Mirror)</a><br>• Made by <a href=\"https://librete.ch\" target=\"_blank\">LibreTECH</a> · <a href=\"https://www.linkedin.com/in/michael-werner-czechowski\" target=\"_blank\">Michael Czechowski</a>",
"task": "Click Next to continue",
"previewHTML": "<p>Hello World! 🌍</p><p>Hallo Welt!</p><p>Bonjour le monde!</p><p>¡Hola Mundo!</p><p>Ciao Mondo!</p><p>Olá Mundo!</p><p>こんにちは世界!</p><p>你好世界!</p><p>안녕 세상!</p><p>Привет мир!</p><p dir=\"rtl\">שלום עולם!</p><p dir=\"rtl\">مرحبا بالعالم!</p>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 12px; } p { margin: 6px 0; padding: 6px 12px; border-radius: 6px; font-weight: 600; font-size: 0.95em; } p:nth-child(1) { background: #fef3c7; color: #92400e; font-size: 1.2em; } p:nth-child(2) { background: #dcfce7; color: #166534; } p:nth-child(3) { background: #dbeafe; color: #1e40af; } p:nth-child(4) { background: #fce7f3; color: #9d174d; } p:nth-child(5) { background: #e0e7ff; color: #4338ca; } p:nth-child(6) { background: #fef9c3; color: #854d0e; } p:nth-child(7) { background: #fee2e2; color: #991b1b; } p:nth-child(8) { background: #f3e8ff; color: #7c3aed; } p:nth-child(9) { background: #ccfbf1; color: #0f766e; } p:nth-child(10) { background: #fae8ff; color: #86198f; } p:nth-child(11) { background: #fef3c7; color: #b45309; } p:nth-child(12) { background: #d1fae5; color: #047857; }",
"sandboxCSS": "",
"initialCode": "<p>Hello World! 🌍</p>\n<p>Hallo Welt!</p>\n<p>Bonjour le monde!</p>\n<p>¡Hola Mundo!</p>\n<p>Ciao Mondo!</p>\n<p>こんにちは世界!</p>\n<p>Привет мир!</p>\n<p dir=\"rtl\">مرحبا بالعالم!</p>",
"solution": "<p>Hello World! 🌍</p>\n<p>Hallo Welt!</p>\n<p>Bonjour le monde!</p>\n<p>¡Hola Mundo!</p>\n<p>Ciao Mondo!</p>\n<p>こんにちは世界!</p>\n<p>Привет мир!</p>\n<p dir=\"rtl\">مرحبا بالعالم!</p>",
"initialCode": "<p>Hello World! 🌍</p>\n<p>Hallo Welt!</p>\n<p>Bonjour le monde!</p>\n<p>¡Hola Mundo!</p>\n<p>Ciao Mondo!</p>\n<p>Olá Mundo!</p>\n<p>こんにちは世界!</p>\n<p>你好世界!</p>\n<p>안녕 세상!</p>\n<p>Привет мир!</p>\n<p dir=\"rtl\">שלום עולם!</p>\n<p dir=\"rtl\">مرحبا بالعالم!</p>",
"solution": "<p>Hello World! 🌍</p>\n<p>Hallo Welt!</p>\n<p>Bonjour le monde!</p>\n<p>¡Hola Mundo!</p>\n<p>Ciao Mondo!</p>\n<p>Olá Mundo!</p>\n<p>こんにちは世界!</p>\n<p>你好世界!</p>\n<p>안녕 세상!</p>\n<p>Привет мир!</p>\n<p dir=\"rtl\">שלום עולם!</p>\n<p dir=\"rtl\">مرحبا بالعالم!</p>",
"previewContainer": "preview-area",
"validations": [
{
"type": "contains",
"value": "go",
"message": "Write 'Let's go!'"
"value": "Hello",
"message": "Click Next to continue"
}
]
}

View File

@@ -27,20 +27,20 @@
},
{
"id": "get-started",
"title": "Los geht's!",
"description": "<strong>Du bist bereit!</strong> Öffne das Menü (☰) um alle Module zu erkunden.<br><br><strong>Empfohlener Lernpfad:</strong><br>1. <em>HTML Block & Inline</em> - Container vs Inline-Elemente verstehen<br>2. <em>HTML Formulare</em> - Interaktive Formulare mit Validierung erstellen<br>3. <em>CSS Selektoren</em> - Elemente präzise ansprechen<br>4. <em>CSS Box-Model</em> - Padding, Margin, Borders meistern<br>5. <em>CSS Flexbox</em> - Flexible Layouts erstellen<br>6. <em>CSS Animationen</em> - Bewegung und Übergänge hinzufügen<br><br><strong>Tipps:</strong><br>• Nutze <em>Lösung einblenden</em> um das Zielergebnis zu sehen<br>• Dein Fortschritt wird automatisch gespeichert<br>• Probiere Emmet im HTML-Modus: <kbd>ul>li*3</kbd> + Tab<br><br><strong>Open Source:</strong><br>• <a href=\"https://github.com/nextlevelshit/code-crispies\" target=\"_blank\">GitHub</a> · <a href=\"https://git.librete.ch/libretech/code-crispies\" target=\"_blank\">Gitea</a><br>• Entwickelt von <a href=\"https://librete.ch\" target=\"_blank\">librete.ch</a> · <a href=\"https://www.linkedin.com/in/michael-werner-czechowski\" target=\"_blank\">LinkedIn</a>",
"task": "Los geht's!",
"previewHTML": "<p>Hello World! 🌍</p><p>Hallo Welt!</p><p>Bonjour le monde!</p><p>¡Hola Mundo!</p><p>Ciao Mondo!</p><p>こんにちは世界!</p><p>Привет мир!</p><p dir=\"rtl\">مرحبا بالعالم!</p>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 16px; } p { margin: 8px 0; padding: 8px 16px; border-radius: 8px; font-weight: 600; } p:nth-child(1) { background: #fef3c7; color: #92400e; font-size: 1.4em; } p:nth-child(2) { background: #dcfce7; color: #166534; font-size: 1.2em; } p:nth-child(3) { background: #dbeafe; color: #1e40af; font-size: 1.1em; } p:nth-child(4) { background: #fce7f3; color: #9d174d; } p:nth-child(5) { background: #e0e7ff; color: #4338ca; font-size: 1.3em; } p:nth-child(6) { background: #fef9c3; color: #854d0e; } p:nth-child(7) { background: #fee2e2; color: #991b1b; font-size: 1.1em; } p:nth-child(8) { background: #f3e8ff; color: #7c3aed; }",
"title": "Viel Erfolg!",
"description": "<strong>Du bist bereit!</strong> Öffne das Menü (☰) um alle Module zu erkunden.<br><br><strong>Empfohlener Lernpfad:</strong><br>1. <em>HTML Block & Inline</em> - Container vs Inline-Elemente verstehen<br>2. <em>HTML Formulare</em> - Interaktive Formulare mit Validierung erstellen<br>3. <em>CSS Selektoren</em> - Elemente präzise ansprechen<br>4. <em>CSS Box-Model</em> - Padding, Margin, Borders meistern<br>5. <em>CSS Flexbox</em> - Flexible Layouts erstellen<br>6. <em>CSS Animationen</em> - Bewegung und Übergänge hinzufügen<br><br><strong>Tipps:</strong><br>• Nutze <em>Lösung einblenden</em> um das Zielergebnis zu sehen<br>• Dein Fortschritt wird automatisch gespeichert<br>• Probiere Emmet im HTML-Modus: <kbd>ul>li*3</kbd> + Tab<br><br><strong>Open Source:</strong><br>• <a href=\"https://git.librete.ch/libretech/code-crispies\" target=\"_blank\">Gitea (Source)</a> · <a href=\"https://github.com/nextlevelshit/code-crispies\" target=\"_blank\">GitHub (Mirror)</a><br>• Entwickelt von <a href=\"https://librete.ch\" target=\"_blank\">LibreTECH</a> · <a href=\"https://www.linkedin.com/in/michael-werner-czechowski\" target=\"_blank\">Michael Czechowski</a>",
"task": "Klicke auf Weiter",
"previewHTML": "<p>Hello World! 🌍</p><p>Hallo Welt!</p><p>Bonjour le monde!</p><p>¡Hola Mundo!</p><p>Ciao Mondo!</p><p>Olá Mundo!</p><p>こんにちは世界!</p><p>你好世界!</p><p>안녕 세상!</p><p>Привет мир!</p><p dir=\"rtl\">שלום עולם!</p><p dir=\"rtl\">مرحبا بالعالم!</p>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 12px; } p { margin: 6px 0; padding: 6px 12px; border-radius: 6px; font-weight: 600; font-size: 0.95em; } p:nth-child(1) { background: #fef3c7; color: #92400e; font-size: 1.2em; } p:nth-child(2) { background: #dcfce7; color: #166534; } p:nth-child(3) { background: #dbeafe; color: #1e40af; } p:nth-child(4) { background: #fce7f3; color: #9d174d; } p:nth-child(5) { background: #e0e7ff; color: #4338ca; } p:nth-child(6) { background: #fef9c3; color: #854d0e; } p:nth-child(7) { background: #fee2e2; color: #991b1b; } p:nth-child(8) { background: #f3e8ff; color: #7c3aed; } p:nth-child(9) { background: #ccfbf1; color: #0f766e; } p:nth-child(10) { background: #fae8ff; color: #86198f; } p:nth-child(11) { background: #fef3c7; color: #b45309; } p:nth-child(12) { background: #d1fae5; color: #047857; }",
"sandboxCSS": "",
"initialCode": "<p>Hello World! 🌍</p>\n<p>Hallo Welt!</p>\n<p>Bonjour le monde!</p>\n<p>¡Hola Mundo!</p>\n<p>Ciao Mondo!</p>\n<p>こんにちは世界!</p>\n<p>Привет мир!</p>\n<p dir=\"rtl\">مرحبا بالعالم!</p>",
"solution": "<p>Hello World! 🌍</p>\n<p>Hallo Welt!</p>\n<p>Bonjour le monde!</p>\n<p>¡Hola Mundo!</p>\n<p>Ciao Mondo!</p>\n<p>こんにちは世界!</p>\n<p>Привет мир!</p>\n<p dir=\"rtl\">مرحبا بالعالم!</p>",
"initialCode": "<p>Hello World! 🌍</p>\n<p>Hallo Welt!</p>\n<p>Bonjour le monde!</p>\n<p>¡Hola Mundo!</p>\n<p>Ciao Mondo!</p>\n<p>Olá Mundo!</p>\n<p>こんにちは世界!</p>\n<p>你好世界!</p>\n<p>안녕 세상!</p>\n<p>Привет мир!</p>\n<p dir=\"rtl\">שלום עולם!</p>\n<p dir=\"rtl\">مرحبا بالعالم!</p>",
"solution": "<p>Hello World! 🌍</p>\n<p>Hallo Welt!</p>\n<p>Bonjour le monde!</p>\n<p>¡Hola Mundo!</p>\n<p>Ciao Mondo!</p>\n<p>Olá Mundo!</p>\n<p>こんにちは世界!</p>\n<p>你好世界!</p>\n<p>안녕 세상!</p>\n<p>Привет мир!</p>\n<p dir=\"rtl\">שלום עולם!</p>\n<p dir=\"rtl\">مرحبا بالعالم!</p>",
"previewContainer": "preview-area",
"validations": [
{
"type": "contains",
"value": "geht",
"message": "Schreibe 'Los geht's!'"
"value": "Hello",
"message": "Klicke auf Weiter"
}
]
}

View File

@@ -18,7 +18,12 @@
"codeSuffix": "}",
"previewContainer": "preview-area",
"validations": [
{ "type": "contains", "value": "transition", "message": "Verwende die <kbd>transition</kbd> Eigenschaft", "options": { "caseSensitive": false } },
{
"type": "contains",
"value": "transition",
"message": "Verwende die <kbd>transition</kbd> Eigenschaft",
"options": { "caseSensitive": false }
},
{
"type": "regex",
"value": "transition:\\s*background-color\\s*0\\.3s",
@@ -66,14 +71,24 @@
"codeSuffix": "}\n.ball { }",
"previewContainer": "preview-area",
"validations": [
{ "type": "contains", "value": "@keyframes bounce", "message": "Definiere <kbd>@keyframes bounce</kbd>", "options": { "caseSensitive": false } },
{
"type": "contains",
"value": "@keyframes bounce",
"message": "Definiere <kbd>@keyframes bounce</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "regex",
"value": "50%.*transform: translateY\\(-20px\\)",
"message": "Bei <kbd>50%</kbd>, setze <kbd>transform: translateY(-20px)</kbd>",
"options": { "caseSensitive": false }
},
{ "type": "contains", "value": "animation", "message": "Verwende <kbd>animation</kbd> Eigenschaft auf <kbd>.ball</kbd>", "options": { "caseSensitive": false } },
{
"type": "contains",
"value": "animation",
"message": "Verwende <kbd>animation</kbd> Eigenschaft auf <kbd>.ball</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "regex",
"value": "animation:.*bounce.*1s.*infinite",
@@ -113,8 +128,16 @@
"message": "Verwende <kbd>animation-fill-mode</kbd>",
"options": { "caseSensitive": false }
},
{ "type": "property_value", "value": { "property": "animation-duration", "expected": "2s" }, "message": "Setze <kbd>animation-duration: 2s</kbd>" },
{ "type": "property_value", "value": { "property": "animation-delay", "expected": "1s" }, "message": "Setze <kbd>animation-delay: 1s</kbd>" },
{
"type": "property_value",
"value": { "property": "animation-duration", "expected": "2s" },
"message": "Setze <kbd>animation-duration: 2s</kbd>"
},
{
"type": "property_value",
"value": { "property": "animation-delay", "expected": "1s" },
"message": "Setze <kbd>animation-delay: 1s</kbd>"
},
{
"type": "property_value",
"value": { "property": "animation-iteration-count", "expected": "2" },

View File

@@ -603,7 +603,7 @@ function runCode() {
elements.previewWrapper?.classList.add("matched");
setTimeout(() => {
elements.previewWrapper?.classList.remove("matched");
}, 5000);
}, 10000);
updateNavigationButtons();
updateProgressDisplay();

View File

@@ -83,7 +83,7 @@ const translations = {
// Contact
contactTitle: "Contact & Links",
contactText: "Code Crispies is developed by librete.ch",
contactText: "Code Crispies is developed by <a href=\"https://librete.ch\" target=\"_blank\">LibreTECH</a>",
// Reset dialog
resetDialogTitle: "Reset Progress",
@@ -182,7 +182,7 @@ const translations = {
// Contact
contactTitle: "Kontakt & Links",
contactText: "Code Crispies wird von librete.ch entwickelt",
contactText: "Code Crispies wird von <a href=\"https://librete.ch\" target=\"_blank\">LibreTECH</a> entwickelt",
// Reset dialog
resetDialogTitle: "Fortschritt zurücksetzen",

View File

@@ -120,8 +120,9 @@
<footer class="app-footer">
<span data-i18n="openSource">Open Source:</span>
<a href="https://git.librete.ch/libretech/code-crispies" target="_blank">Gitea</a>
<span data-i18n="by">by</span> <a href="https://librete.ch" title="librete.ch">librete.ch</a>
<a href="https://git.librete.ch/libretech/code-crispies" target="_blank">Gitea (Source)</a> ·
<a href="https://github.com/nextlevelshit/code-crispies" target="_blank">GitHub (Mirror)</a>
<span data-i18n="by">by</span> <a href="https://librete.ch" title="LibreTECH">LibreTECH</a>
</footer>
</aside>
@@ -163,7 +164,6 @@
<h4 data-i18n="keyboardShortcutsTitle">Keyboard Shortcuts</h4>
<ul>
<li data-i18n-html="shortcutRun"><kbd>Ctrl+Enter</kbd> - Validate immediately</li>
<li data-i18n-html="shortcutUndo"><kbd>Ctrl+Z</kbd> - Undo</li>
<li data-i18n-html="shortcutRedo"><kbd>Ctrl+Shift+Z</kbd> - Redo</li>
</ul>
@@ -178,24 +178,23 @@
</ul>
<h4 data-i18n="moreProjectsTitle">More Projects</h4>
<ul>
<li>
<a href="https://nextlevelshit.github.io/html-over-js/" target="_blank"><strong>HTML over JS</strong></a>
<div class="project-cards">
<a href="https://nextlevelshit.github.io/html-over-js/" target="_blank" class="project-card">
<strong>HTML over JS</strong>
<span data-i18n="htmlOverJsDesc"> - Learn to leverage native HTML elements instead of custom JavaScript solutions</span>
</li>
<li>
<a href="https://nextlevelshit.github.io/web-engineering-mandala/" target="_blank"><strong>Web Engineering Mandala</strong></a>
</a>
<a href="https://nextlevelshit.github.io/web-engineering-mandala/" target="_blank" class="project-card">
<strong>Web Engineering Mandala</strong>
<span data-i18n="mandalaDesc"> - Interactive visualization of JavaScript technologies organized by complexity</span>
</li>
</ul>
</a>
</div>
<h4 data-i18n="contactTitle">Contact & Links</h4>
<p data-i18n="contactText">Code Crispies is developed by librete.ch</p>
<p data-i18n-html="contactText">Code Crispies is developed by <a href="https://librete.ch" target="_blank">LibreTECH</a></p>
<ul>
<li><a href="https://librete.ch" target="_blank">librete.ch</a></li>
<li><a href="https://github.com/nextlevelshit/code-crispies" target="_blank">GitHub</a></li>
<li><a href="https://git.librete.ch/libretech/code-crispies" target="_blank">Gitea</a></li>
<li><a href="https://www.linkedin.com/in/michael-werner-czechowski" target="_blank">LinkedIn</a></li>
<li><a href="https://git.librete.ch/libretech/code-crispies" target="_blank">Gitea</a> Self-hosted source repository</li>
<li><a href="https://github.com/nextlevelshit/code-crispies" target="_blank">GitHub</a> Public mirror</li>
<li><a href="https://www.linkedin.com/in/michael-werner-czechowski" target="_blank">LinkedIn</a> Michael Czechowski</li>
</ul>
</div>
</dialog>

View File

@@ -595,7 +595,7 @@ code, kbd {
border-radius: var(--border-radius-lg);
font-weight: bold;
font-size: 1.1rem;
animation: dvd-bounce 4s ease-in-out infinite;
animation: dvd-bounce 8s ease-in-out infinite;
z-index: 10;
white-space: nowrap;
}
@@ -914,7 +914,6 @@ button.lesson-list-item {
.editor-tools {
display: flex;
gap: 4px;
margin-right: var(--spacing-sm);
}
.btn-ghost {
@@ -954,6 +953,11 @@ button.lesson-list-item {
border-color: var(--primary-dark);
}
/* Hide Run button - live preview is stable */
#run-btn {
display: none;
}
/* ================= TOGGLE SWITCH ================= */
.toggle-switch {
display: flex;
@@ -1105,6 +1109,45 @@ input:checked + .toggle-slider::before {
margin-top: var(--spacing-lg);
}
/* Project Cards in Help Dialog */
.project-cards {
display: flex;
flex-direction: column;
gap: var(--spacing-sm);
margin-bottom: var(--spacing-md);
}
.project-card {
display: block;
padding: var(--spacing-md);
background: var(--primary-bg-light);
border-radius: var(--border-radius-md);
border: 1px solid var(--primary-bg-medium);
text-decoration: none;
color: var(--text-color);
transition: all 0.2s ease;
}
.project-card:hover {
background: var(--primary-bg-medium);
border-color: var(--primary-color);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(94, 75, 139, 0.15);
}
.project-card strong {
display: block;
color: var(--primary-color);
font-size: 1rem;
margin-bottom: 4px;
}
.project-card span {
font-size: 0.9rem;
color: var(--light-text);
line-height: 1.4;
}
/* ================= FOOTER ================= */
.app-footer {
padding: var(--spacing-md);