feat: add JavaScript learning section with starter lessons and sidebar section headers

Implementation following plan:
- S01: Foundation: schema, section config, and router
- S02: Install CodeMirror JavaScript language support
- S03: Create JavaScript lesson JSON files (variables, DOM, events)
- S04: Register JavaScript lessons in module stores
- S05: Add JavaScript validation logic
- S06: Add JavaScript mode to LessonEngine preview rendering
- S07: Add JavaScript mode to CodeEditor
- S08: Update app.js for JavaScript mode support
- S09: Update navigation HTML and CSS theming for JavaScript section
- S10: Add section grouping headers in sidebar navigation
- S11: Update and write tests
This commit is contained in:
2026-03-28 20:22:50 +01:00
parent a54828815d
commit b9c90112a3
20 changed files with 863 additions and 27 deletions

View File

@@ -291,6 +291,14 @@ kbd {
background: #5b8dd9;
}
[data-section="javascript"] .logo h1 .code-text {
color: #d4a017;
}
[data-section="javascript"] .logo h1 .crispies-text {
background: #d4a017;
}
.help-toggle {
width: 28px;
height: 28px;
@@ -1244,6 +1252,22 @@ nav.sidebar-section:not(.sidebar-nav-mobile) {
animation: milestone-pop 0.5s ease-out;
}
/* Sidebar section grouping headers */
.sidebar-section-header {
font-size: 0.7rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--light-text);
padding: 0.75rem 0.75rem 0.25rem;
margin: 0.5rem 0 0;
border-left: 3px solid transparent;
}
.sidebar-section-header:first-child {
margin-top: 0;
}
/* Module List in Sidebar */
.module-list {
/* No max-height - parent nav.sidebar-section handles overflow */
@@ -3618,6 +3642,14 @@ input:checked + .toggle-slider::before {
--section-color-rgb: 91, 141, 217;
}
/* JavaScript Section - Gold */
[data-section="javascript"] {
--section-color: #d4a017;
--section-color-light: #e0b840;
--section-color-dark: #b08610;
--section-color-rgb: 212, 160, 23;
}
/* Apply section colors to nav links */
.nav-link[data-section="css"] {
color: #d95a8a;
@@ -3635,6 +3667,10 @@ input:checked + .toggle-slider::before {
color: #5b8dd9;
}
.nav-link[data-section="javascript"] {
color: #d4a017;
}
.nav-link[data-section="css"]:hover,
.nav-link[data-section="css"].active {
background: rgba(217, 90, 138, 0.1);
@@ -3659,6 +3695,12 @@ input:checked + .toggle-slider::before {
color: #4070b8;
}
.nav-link[data-section="javascript"]:hover,
.nav-link[data-section="javascript"].active {
background: rgba(212, 160, 23, 0.1);
color: #b08610;
}
/* Hint section colors */
body[data-section="css"] .hint {
background: rgba(217, 90, 138, 0.3);
@@ -3696,6 +3738,15 @@ body[data-section="markdown"] .hint-progress {
background: #5b8dd9;
}
body[data-section="javascript"] .hint {
background: rgba(212, 160, 23, 0.3);
border-left-color: #e0b840;
}
body[data-section="javascript"] .hint-progress {
background: #d4a017;
}
/* RTL hint border */
[dir="rtl"] body[data-section="css"] .hint {
border-right-color: #a98cd6;
@@ -3713,6 +3764,10 @@ body[data-section="markdown"] .hint-progress {
border-right-color: #7ba3e5;
}
[dir="rtl"] body[data-section="javascript"] .hint {
border-right-color: #e0b840;
}
/* Reference nav link colors */
.ref-nav-link[data-ref="css"],
.ref-nav-link[data-ref="selectors"],
@@ -3816,6 +3871,24 @@ body[data-section="markdown"] .cm-editor .cm-activeLine {
background-color: rgba(91, 141, 217, 0.08) !important;
}
body[data-section="javascript"] .cm-editor .cm-content {
caret-color: #d4a017 !important;
}
body[data-section="javascript"] .cm-editor .cm-cursor,
body[data-section="javascript"] .cm-editor .cm-dropCursor {
border-left-color: #d4a017 !important;
}
body[data-section="javascript"] .cm-editor .cm-selectionBackground,
body[data-section="javascript"] .cm-editor .cm-content ::selection {
background-color: rgba(212, 160, 23, 0.25) !important;
}
body[data-section="javascript"] .cm-editor .cm-activeLine {
background-color: rgba(212, 160, 23, 0.08) !important;
}
/* Module pill section colors */
body[data-section="css"] .module-pill {
background: rgba(217, 90, 138, 0.1);
@@ -3853,6 +3926,15 @@ body[data-section="markdown"] .module-pill .level-indicator {
color: #4070b8;
}
body[data-section="javascript"] .module-pill {
background: rgba(212, 160, 23, 0.1);
color: #d4a017;
}
body[data-section="javascript"] .module-pill .level-indicator {
color: #b08610;
}
/* Code block border section colors */
body[data-section="css"] .code-block {
border-color: rgba(217, 90, 138, 0.4);
@@ -3870,6 +3952,10 @@ body[data-section="markdown"] .code-block {
border-color: rgba(91, 141, 217, 0.4);
}
body[data-section="javascript"] .code-block {
border-color: rgba(212, 160, 23, 0.4);
}
/* Section code block CodeMirror syntax highlighting overrides */
body[data-section="css"] .code-block .cm-editor .cm-line {
color: #c9c0e0;
@@ -3887,6 +3973,10 @@ body[data-section="markdown"] .code-block .cm-editor .cm-line {
color: #c0d0e8;
}
body[data-section="javascript"] .code-block .cm-editor .cm-line {
color: #e0d8b0;
}
/* Task instruction bubble section colors */
[data-section="css"] .task-instruction {
background: rgba(217, 90, 138, 0.92);
@@ -3904,6 +3994,10 @@ body[data-section="markdown"] .code-block .cm-editor .cm-line {
background: rgba(91, 141, 217, 0.92);
}
[data-section="javascript"] .task-instruction {
background: rgba(212, 160, 23, 0.92);
}
/* Section page progress bar colors */
body[data-section="css"] .section-progress-bar .progress-fill {
background: #d95a8a;
@@ -3921,6 +4015,10 @@ body[data-section="markdown"] .section-progress-bar .progress-fill {
background: #5b8dd9;
}
body[data-section="javascript"] .section-progress-bar .progress-fill {
background: #d4a017;
}
/* Section page header colors */
[data-section="css"] .section-hero h1 {
color: #d95a8a;
@@ -3938,6 +4036,10 @@ body[data-section="markdown"] .section-progress-bar .progress-fill {
color: #5b8dd9;
}
[data-section="javascript"] .section-hero h1 {
color: #d4a017;
}
/* Lesson title h2 section colors */
body[data-section="css"] #lesson-title {
color: #d95a8a;
@@ -3955,6 +4057,10 @@ body[data-section="markdown"] #lesson-title {
color: #5b8dd9;
}
body[data-section="javascript"] #lesson-title {
color: #d4a017;
}
/* Section and Reference footer - override landing-footer styles */
.section-footer.landing-footer,
.reference-footer.landing-footer {