feat: add contact section and smooth lesson transitions
- Add contact section to help dialog with librete.ch, GitHub, Gitea, LinkedIn links - Add HTML/CSS prefixes to English module titles for consistency with German - Add CSS transitions for smooth lesson switching - Add transitioning class to prevent content flash during lesson changes
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../schemas/code-crispies-module-schema.json",
|
||||
"id": "css-basic-selectors",
|
||||
"title": "Selectors",
|
||||
"title": "CSS Selectors",
|
||||
"description": "CSS selectors are the foundation of styling web pages, allowing you to target specific HTML elements for styling. This module introduces fundamental selector types including element type selectors, class selectors, ID selectors, and the universal selector.",
|
||||
"difficulty": "beginner",
|
||||
"lessons": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../schemas/code-crispies-module-schema.json",
|
||||
"id": "box-model",
|
||||
"title": "Box Model",
|
||||
"title": "CSS Box Model",
|
||||
"description": "Master the fundamental principles of space management in web design through the CSS box model. This module explores how content, padding, borders, and margins combine to create layout structures that are both visually appealing and structurally sound.",
|
||||
"difficulty": "beginner",
|
||||
"lessons": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../schemas/code-crispies-module-schema.json",
|
||||
"id": "units-variables",
|
||||
"title": "Units & Vars",
|
||||
"title": "CSS Units & Variables",
|
||||
"description": "Understand the variety of CSS measurement units and how to define and use custom properties for maintainable styles.",
|
||||
"difficulty": "beginner",
|
||||
"lessons": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../schemas/code-crispies-module-schema.json",
|
||||
"id": "transitions-animations",
|
||||
"title": "Animations",
|
||||
"title": "CSS Animations",
|
||||
"description": "Bring interactivity to your UI by smoothly transitioning properties and creating keyframe-driven animations.",
|
||||
"difficulty": "beginner",
|
||||
"lessons": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../schemas/code-crispies-module-schema.json",
|
||||
"id": "responsive-design",
|
||||
"title": "Responsive",
|
||||
"title": "CSS Responsive Design",
|
||||
"description": "Make your layouts adapt to different screen sizes using media queries and fluid design techniques.",
|
||||
"difficulty": "intermediate",
|
||||
"lessons": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../schemas/code-crispies-module-schema.json",
|
||||
"id": "html-elements",
|
||||
"title": "HTML Elements",
|
||||
"title": "HTML Block & Inline",
|
||||
"description": "Understanding the fundamental difference between container (block) and inline elements",
|
||||
"mode": "html",
|
||||
"difficulty": "beginner",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../schemas/code-crispies-module-schema.json",
|
||||
"id": "html-forms-basic",
|
||||
"title": "Form Inputs",
|
||||
"title": "HTML Forms",
|
||||
"description": "Learn to create forms with various input types",
|
||||
"mode": "html",
|
||||
"difficulty": "beginner",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../schemas/code-crispies-module-schema.json",
|
||||
"id": "html-forms-validation",
|
||||
"title": "Validation",
|
||||
"title": "HTML Validation",
|
||||
"description": "Learn HTML5 built-in form validation attributes",
|
||||
"mode": "html",
|
||||
"difficulty": "intermediate",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../schemas/code-crispies-module-schema.json",
|
||||
"id": "html-details-summary",
|
||||
"title": "Disclosure",
|
||||
"title": "HTML Details & Summary",
|
||||
"description": "Create expandable content sections without JavaScript",
|
||||
"mode": "html",
|
||||
"difficulty": "beginner",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../schemas/code-crispies-module-schema.json",
|
||||
"id": "html-progress-meter",
|
||||
"title": "Progress/Meter",
|
||||
"title": "HTML Progress & Meter",
|
||||
"description": "Display completion status and scalar measurements natively",
|
||||
"mode": "html",
|
||||
"difficulty": "beginner",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../schemas/code-crispies-module-schema.json",
|
||||
"id": "html-tables",
|
||||
"title": "Tables",
|
||||
"title": "HTML Tables",
|
||||
"description": "Create structured data tables with headers and captions",
|
||||
"mode": "html",
|
||||
"difficulty": "beginner",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../schemas/code-crispies-module-schema.json",
|
||||
"id": "html-marquee",
|
||||
"title": "Marquee",
|
||||
"title": "HTML Marquee",
|
||||
"description": "Create scrolling text with the classic (deprecated but fun!) marquee element",
|
||||
"mode": "html",
|
||||
"difficulty": "beginner",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../schemas/code-crispies-module-schema.json",
|
||||
"id": "html-svg",
|
||||
"title": "SVG",
|
||||
"title": "HTML SVG",
|
||||
"description": "Draw scalable vector graphics directly in HTML",
|
||||
"mode": "html",
|
||||
"difficulty": "beginner",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../schemas/code-crispies-module-schema.json",
|
||||
"id": "flexbox",
|
||||
"title": "Flexbox",
|
||||
"title": "CSS Flexbox",
|
||||
"description": "Master the flexible box layout model for modern responsive designs",
|
||||
"difficulty": "intermediate",
|
||||
"lessons": [
|
||||
|
||||
@@ -20,6 +20,7 @@ const elements = {
|
||||
helpBtn: document.getElementById("help-btn"),
|
||||
|
||||
// Left panel
|
||||
editorSection: document.querySelector(".editor-section"),
|
||||
modulePill: document.getElementById("module-pill"),
|
||||
moduleName: document.querySelector(".module-name"),
|
||||
lessonTitle: document.getElementById("lesson-title"),
|
||||
@@ -313,6 +314,9 @@ function loadCurrentLesson() {
|
||||
const lesson = engineState.lesson;
|
||||
const mode = lesson.mode || engineState.module?.mode || "css";
|
||||
|
||||
// Add transition class for smooth content swap
|
||||
elements.editorSection?.classList.add("transitioning");
|
||||
|
||||
// Update UI based on mode
|
||||
updateEditorForMode(mode);
|
||||
|
||||
@@ -388,6 +392,11 @@ function loadCurrentLesson() {
|
||||
|
||||
// Render the expected/solution preview
|
||||
lessonEngine.renderExpectedPreview();
|
||||
|
||||
// Remove transition class after content is updated
|
||||
requestAnimationFrame(() => {
|
||||
elements.editorSection?.classList.remove("transitioning");
|
||||
});
|
||||
}
|
||||
|
||||
// ================= LIVE PREVIEW =================
|
||||
|
||||
@@ -76,6 +76,10 @@ const translations = {
|
||||
emmetNested: "<kbd>form>input+button</kbd> → nested structure",
|
||||
emmetContent: "<kbd>p{Hello}</kbd> → p with text content",
|
||||
|
||||
// Contact
|
||||
contactTitle: "Contact & Links",
|
||||
contactText: "Code Crispies is developed by librete.ch",
|
||||
|
||||
// Reset dialog
|
||||
resetDialogTitle: "Reset Progress",
|
||||
resetDialogText: "Are you sure you want to reset all your progress? This cannot be undone.",
|
||||
@@ -165,6 +169,10 @@ const translations = {
|
||||
emmetNested: "<kbd>form>input+button</kbd> → verschachtelte Struktur",
|
||||
emmetContent: "<kbd>p{Hallo}</kbd> → p mit Textinhalt",
|
||||
|
||||
// Contact
|
||||
contactTitle: "Kontakt & Links",
|
||||
contactText: "Code Crispies wird von librete.ch entwickelt",
|
||||
|
||||
// Reset dialog
|
||||
resetDialogTitle: "Fortschritt zurücksetzen",
|
||||
resetDialogText: "Bist du sicher, dass du deinen gesamten Fortschritt zurücksetzen möchtest? Dies kann nicht rückgängig gemacht werden.",
|
||||
|
||||
@@ -178,6 +178,15 @@
|
||||
<li data-i18n-html="emmetNested"><kbd>form>input+button</kbd> → nested structure</li>
|
||||
<li data-i18n-html="emmetContent"><kbd>p{Hello}</kbd> → p with text content</li>
|
||||
</ul>
|
||||
|
||||
<h4 data-i18n="contactTitle">Contact & Links</h4>
|
||||
<p data-i18n="contactText">Code Crispies is developed by librete.ch</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/public/code-crispies" target="_blank">Gitea</a></li>
|
||||
<li><a href="https://www.linkedin.com/in/michael-werner-czechowski" target="_blank">LinkedIn</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
|
||||
13
src/main.css
13
src/main.css
@@ -228,6 +228,19 @@ code, kbd {
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
/* Smooth lesson transition */
|
||||
#lesson-title,
|
||||
.lesson-description,
|
||||
.task-instruction {
|
||||
transition: opacity 0.1s ease;
|
||||
}
|
||||
|
||||
.editor-section.transitioning #lesson-title,
|
||||
.editor-section.transitioning .lesson-description,
|
||||
.editor-section.transitioning .task-instruction {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.module-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user