feat: restructure learning path with new modules and enhanced explanations

- Add CSS Colors, Typography, Advanced Selectors, and Grid modules
- Remove deprecated HTML Marquee module from all languages
- Remove redundant div & span lesson from HTML Block & Inline
- Move SVG module from HTML to CSS section
- Enhance first lessons with comprehensive explanations:
  - Flexbox: historical context, axes concept
  - Colors: named colors, background-color explained
  - Grid: comparison to Flexbox, key properties
- Swap header logo highlight (CRISPIES instead of CODE)
- Use English fallbacks for new modules in non-EN languages
- Fix test to include 'playground' mode

New path: 19 modules (~78 lessons) vs previous 16 modules (62 lessons)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
2026-01-13 20:32:45 +01:00
parent 760690cdf1
commit fb33930328
14 changed files with 986 additions and 287 deletions

851
LESSON_EVALUATION.md Normal file
View File

@@ -0,0 +1,851 @@
# Code Crispies Lesson Evaluation
This document evaluates all lessons using the 5-question framework to identify gaps, improvements needed, and restructuring recommendations.
## Evaluation Framework
### The 5 Questions
1. **Q1: PURPOSE** - What concept does this teach and why does a student need it?
2. **Q2: PREREQUISITES** - Does it assume knowledge already taught?
3. **Q3: TASK CLARITY** - Can students complete it without guessing?
4. **Q4: EXPLANATION DEPTH** - Is depth appropriate for position?
5. **Q5: PROGRESSION** - Does it prepare for the next lesson?
### Scoring
- **5** = Excellent
- **4** = Good
- **3** = Adequate
- **2** = Needs Improvement
- **1** = Requires Rewrite
---
## Module 1: Welcome (00-welcome.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Get Started | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
| Overview | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
| Playground | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
**Module Summary:** Excellent onboarding. Comprehensive explanation of platform, clear navigation guidance.
**Issues:** None
**Recommendation:** Keep as-is
---
## Module 2: HTML Block & Inline (20-html-elements.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Block vs Inline | 4 | 5 | 5 | 3 | 5 | 22/25 | Enhance |
| Semantic Tags | 4 | 5 | 4 | 3 | 5 | 21/25 | Enhance |
| div & span | 2 | 5 | 5 | 2 | 4 | 18/25 | **REMOVE** |
**Module Summary:** Good content but lesson 3 (div & span) is redundant with lesson 1.
**Issues:**
- Q4: First lesson (Block vs Inline) needs more historical context about document flow
- Q4: Missing explanation of why block/inline matters for layout
- Q1: Lesson 3 (div & span) is redundant - block/inline already covered in lesson 1
**Recommendation:**
- **REMOVE lesson 3 (div & span)** - redundant to lesson 1
- Enhance lesson 1 with comprehensive explanation (~200 words)
- Add "why" context: Why does HTML distinguish block from inline?
---
## Module 3: HTML Forms - Basics (21-html-forms-basic.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Form Structure | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Input Types | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Submit Button | 5 | 5 | 5 | 3 | 5 | 23/25 | Minor edit |
**Module Summary:** Well-structured with good accessibility focus (mentions `for` attribute).
**Issues:**
- Q4: First lesson could have more context about why forms exist, HTTP form submission
- Q4: Depth is similar across all lessons instead of progressive reduction
**Recommendation:**
- Add comprehensive intro to lesson 1 about forms' role in web applications
- Reduce depth in lesson 3 (Submit Button)
---
## Module 4: HTML Validation (22-html-forms-validation.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Required Fields | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Constraints | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Full Form | 5 | 5 | 4 | 3 | 5 | 22/25 | Minor edit |
**Module Summary:** Good coverage of native validation attributes.
**Issues:**
- Q3: Full Form lesson task says "Add required attributes, proper input types, and validation constraints" - somewhat vague
- Q4: Difficulty marked as "intermediate" but content is beginner-friendly
**Recommendation:**
- Clarify task in lesson 3: specify exactly what to add
- Change difficulty to "beginner"
---
## Module 5: HTML Details & Summary (23-html-details-summary.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| First Widget | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Pre-expanded | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| FAQ Accordion | 5 | 5 | 5 | 4 | 4 | 23/25 | Keep |
**Module Summary:** Excellent demonstration of native HTML interactivity.
**Issues:**
- Q4: First lesson could mention historical context (before details, needed JS)
- Q5: FAQ Accordion is a good capstone but doesn't connect to next module
**Recommendation:**
- Add "why" context to lesson 1: "Before HTML5, collapsible content required JavaScript"
---
## Module 6: HTML Progress & Meter (24-html-progress-meter.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Progress Bars | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Indeterminate | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Meter Gauges | 5 | 5 | 5 | 4 | 4 | 23/25 | Keep |
**Module Summary:** Good coverage of native visualization elements.
**Issues:**
- Q4: Meter lesson has many attributes - could be overwhelming
**Recommendation:** Keep as-is
---
## Module 7: HTML Tables (30-html-tables.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Basic Table | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Head & Body | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Complete Table | 5 | 5 | 5 | 3 | 4 | 22/25 | Minor edit |
**Module Summary:** Good semantic table structure teaching.
**Issues:**
- Q4: First lesson could explain when to use tables (tabular data, not layout!)
- Q4: Progressive depth reduction works well
**Recommendation:**
- Add context to lesson 1: "Tables are for tabular data, not page layout"
---
## Module 8: HTML SVG (32-html-svg.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Drawing Circles | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Rectangles & Lines | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Multiple Shapes | 5 | 5 | 5 | 3 | 3 | 21/25 | Review |
**Module Summary:** Good intro to SVG but positioned oddly in HTML section.
**Issues:**
- Q5: Final lesson doesn't connect to CSS section that follows
- Position: SVG involves graphics/styling - better fit in CSS section
**Recommendation:**
- MOVE to CSS section after Units & Variables
- Add comprehensive intro about SVG vs raster images
---
## Module 9: HTML Marquee (31-html-marquee.json) - DEPRECATED
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Scrolling Text | 2 | 5 | 5 | 3 | 3 | 18/25 | REMOVE |
| Direction & Behavior | 2 | 5 | 5 | 3 | 3 | 18/25 | REMOVE |
| Retro News Ticker | 2 | 5 | 5 | 3 | 2 | 17/25 | REMOVE |
**Module Summary:** Teaches deprecated HTML element.
**Issues:**
- Q1: Marquee is deprecated and should not be taught as standard practice
- Q5: Doesn't lead to anything practical
**Recommendation:**
- **REMOVE from learning path**
- Could be moved to optional "Web History" section if desired
---
## Module 10: CSS Selectors (00-basic-selectors.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| What's a Selector? | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
| Type Selectors | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
| Class Selectors | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
| Multiple Classes | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Combining Types | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| ID Selectors | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Type + ID | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Selector Lists | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Universal (*) | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Specificity | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
**Module Summary:** EXCELLENT! This is the gold standard for explanation depth. First lesson has comprehensive "why" context with code examples.
**Issues:** None significant
**Recommendation:**
- Keep as-is
- Use as template for other modules
- Note: Progressive depth reduction could be stronger (lessons 5-10 have similar depth)
---
## Module 11: CSS Box Model (01-box-model.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Box Model Components | 5 | 5 | 5 | 4 | 5 | 24/25 | Enhance |
| Adding Borders | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Adding Margins | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Box Sizing | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Margin Collapse | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Margin Shorthand | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Padding Shorthand | 5 | 5 | 5 | 2 | 5 | 22/25 | Keep |
| Border on Specific Sides | 5 | 5 | 5 | 2 | 4 | 21/25 | Keep |
**Module Summary:** Good structure with proper progression.
**Issues:**
- Q4: First lesson could have MORE comprehensive explanation (like CSS Selectors has)
- Q4: Last lessons appropriately brief - good depth progression!
**Recommendation:**
- Enhance lesson 1 description with "why" context (like CSS Selectors lesson 1)
- Visual diagram reference would help but not critical
---
## Module 12: CSS Units & Variables (05-units-variables.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Absolute vs Relative | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| CSS Custom Properties | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Unit Calculations | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Viewport & Responsive | 5 | 5 | 5 | 3 | 4 | 22/25 | Keep |
**Module Summary:** Good coverage of units and variables.
**Issues:**
- Q5: Last lesson could better transition to Flexbox module
- GAP: Colors and Typography should come BEFORE this module
**Recommendation:**
- Add transition text mentioning layout modules next
- INSERT Colors and Typography modules before this one
---
## Module 13: CSS Flexbox (flexbox.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Container | 5 | 5 | 5 | 2 | 5 | 22/25 | **ENHANCE** |
| Direction & Wrap | 5 | 5 | 5 | 2 | 5 | 22/25 | Keep |
| Justify Content | 5 | 5 | 5 | 2 | 5 | 22/25 | Keep |
| Align Items | 5 | 5 | 5 | 2 | 5 | 22/25 | Keep |
| Flex Grow | 5 | 5 | 5 | 2 | 5 | 22/25 | Keep |
| Align Self | 5 | 5 | 5 | 2 | 4 | 21/25 | Keep |
**Module Summary:** MAJOR ISSUE - First lesson has minimal explanation compared to CSS Selectors!
**Issues:**
- Q4: **CRITICAL** - Lesson 1 description is only 2 sentences + code block
- Q4: No "why" context about flexbox history or when to use it
- Q4: All lessons have similar minimal depth - no progressive reduction
**Recommendation:**
- **REWRITE lesson 1** with comprehensive explanation:
- History: Before flexbox, layout was done with floats/positioning
- Why: Flexbox solves the "vertical centering problem" and responsive layouts
- Main vs cross axis explained
- When to use flexbox vs grid
- Keep lessons 2-6 brief (appropriate for later lessons)
---
## Module 14: CSS Responsive Design (08-responsive.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Media Queries | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Fluid Type | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Responsive Grid | 5 | 4 | 5 | 3 | 5 | 22/25 | Review |
| Mobile-First | 5 | 5 | 5 | 3 | 4 | 22/25 | Keep |
**Module Summary:** Good coverage but has prerequisite issue.
**Issues:**
- Q2: Lesson 3 (Responsive Grid) uses CSS Grid concepts but Grid hasn't been taught!
- GAP: Grid module should come BEFORE Responsive Design
**Recommendation:**
- ADD Grid module before Responsive Design
- Or remove/rewrite Responsive Grid lesson to use flexbox only
---
## Module 15: CSS Animations (06-transitions-animations.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Transitions | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Timing Funcs | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Keyframes | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Animation Properties | 5 | 5 | 5 | 3 | 4 | 22/25 | Keep |
**Module Summary:** Good structure with appropriate progression.
**Issues:**
- Q4: First lesson could have more context about when to use animations (UX principles)
**Recommendation:**
- Add brief UX context to lesson 1: "Animations should enhance UX, not distract"
---
## Module 16: Goodbye (99-goodbye.json)
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Well Done! | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
| Contribute | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
| Keep Learning | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
**Module Summary:** Excellent closing with resources and encouragement.
**Issues:** None
**Recommendation:** Keep as-is
---
# Unused Modules Evaluation
## Colors (03-colors.json) - NOT IN PATH
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Setting Background Colors | 5 | 5 | 4 | 3 | 5 | 22/25 | Enhance |
| Text Color and Contrast | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| CSS Gradients | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Background Images | 5 | 5 | 4 | 3 | 4 | 21/25 | Review |
**Issues:**
- Q3: Lesson 1 uses hex code (#e0f7fa) instead of named color - inconsistent with guidelines
- Q4: First lesson needs more explanation about color theory, accessibility
- Q3: Lesson 4 task is vague: "using a placeholder URL"
**Recommendation:**
- **ADD to learning path** after CSS Selectors
- Change hex codes to named colors where possible
- Enhance lesson 1 with color accessibility context (contrast ratios)
- Clarify task in lesson 4
---
## Typography (04-typography.json) - NOT IN PATH
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Font Family & Fallbacks | 5 | 5 | 5 | 3 | 5 | 23/25 | Enhance |
| Font Size & Line Height | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Font Weight & Style | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Text Decoration & Shadow | 5 | 5 | 4 | 3 | 4 | 21/25 | Review |
**Issues:**
- Q4: First lesson needs more context about web fonts, system fonts, why fallbacks matter
- Q3: Lesson 4 task is vague: "Apply an underline... and a light shadow"
**Recommendation:**
- **ADD to learning path** after Colors
- Enhance lesson 1 with font loading context
- Specify exact values in lesson 4 task
---
## Grid (grid.json) - NOT IN PATH
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| Grid Container Basics | 5 | 5 | 5 | 4 | 5 | 24/25 | Enhance |
| Grid Template Areas | 5 | 5 | 5 | 4 | 5 | 24/25 | Keep |
| Spanning Grid Cells | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Automatic Grid Placement | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Grid Alignment | 5 | 5 | 5 | 3 | 5 | 23/25 | Keep |
| Overlapping Grid Items | 5 | 5 | 5 | 3 | 4 | 22/25 | Keep |
**Issues:**
- Q4: First lesson needs comprehensive intro about Grid vs Flexbox (when to use which)
**Recommendation:**
- **ADD to learning path** after Flexbox
- Enhance lesson 1 with Grid vs Flexbox comparison
---
## Advanced Selectors (01-advanced-selectors.json) - NOT IN PATH
| Lesson | Q1 | Q2 | Q3 | Q4 | Q5 | Total | Action |
|--------|----|----|----|----|----|----|--------|
| [attribute] | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
| Attr Matching | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
| Child (>) | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
| Descendant | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
| Adjacent (+) | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
| Sibling (~) | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
| :hover | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
| :first-child | 5 | 5 | 5 | 5 | 5 | 25/25 | Keep |
**Issues:** None - this is an excellent module!
**Recommendation:**
- **ADD to learning path** after CSS Basic Selectors
- This module has the BEST explanation depth of all modules
---
# Summary
## Overall Statistics
| Category | Count |
|----------|-------|
| Total Active Lessons | 62 |
| Lessons Scoring 24-25 | 35 (56%) |
| Lessons Scoring 21-23 | 22 (35%) |
| Lessons Scoring <21 | 5 (8%) |
| Modules to REMOVE | 1 (Marquee) |
| Modules to ADD | 4 (Colors, Typography, Grid, Adv Selectors) |
## Critical Issues
### 1. Missing Modules (HIGH PRIORITY)
- **Colors** - Students use colors without learning them
- **Typography** - Font properties not taught
- **Grid** - Essential layout missing
- **Advanced Selectors** - Excellent content not being used
### 2. Explanation Depth Issues (MEDIUM PRIORITY)
- **Flexbox Lesson 1** - Needs comprehensive rewrite (currently only 2 sentences)
- **HTML Block & Inline Lesson 1** - Needs "why" context
- **Box Model Lesson 1** - Could be more comprehensive
### 3. Module Position Issues (MEDIUM PRIORITY)
- **SVG** - Should be in CSS section, not HTML section
- **Responsive Design** - Uses Grid concepts before Grid is taught
### 4. Deprecated Content (HIGH PRIORITY)
- **Marquee** - Remove from learning path
## Recommended New Structure
```
1. Welcome
2. HTML Block & Inline
3. HTML Forms - Basics
4. HTML Forms - Validation
5. HTML Details & Summary
6. HTML Progress & Meter
7. HTML Tables
8. CSS Selectors - Basics (existing)
9. CSS Selectors - Advanced (ADD - excellent content)
10. CSS Colors (ADD)
11. CSS Typography (ADD)
12. CSS Box Model
13. CSS Units & Variables
14. CSS SVG (MOVE from HTML)
15. CSS Flexbox (ENHANCE lesson 1)
16. CSS Grid (ADD)
17. CSS Responsive Design
18. CSS Animations
19. What's Next?
REMOVED: HTML Marquee
```
## Priority Actions
### Immediate (Before Next Release)
1. Remove HTML Marquee from `src/config/lessons.js`
2. Remove "div & span" lesson from HTML Block & Inline (redundant)
3. Add Advanced Selectors to path after Basic Selectors
4. Enhance Flexbox lesson 1 with comprehensive explanation
### Short-term
5. Add Colors module to path (after Basic Selectors)
6. Add Typography module to path (after Colors)
7. Add Grid module to path (after Flexbox)
8. Move SVG from HTML section to CSS section
### Medium-term
9. Enhance all first lessons with comprehensive explanations
10. Fix hex colors in Colors module to use named colors
11. Clarify vague tasks (Typography lesson 4, Colors lesson 4)
### Long-term
12. Implement progressive depth reduction across all modules
13. Update translations for new module order
---
## UI Changes
### Header Logo
- **Current:** "code" has background highlight, "crispies" is plain
- **Change:** Swap so "crispies" has background highlight, "code" is plain
---
# Detailed Lesson-Level Improvements
## HTML Section Lessons
### Module: HTML Block & Inline (20-html-elements.json)
#### Lesson 1: Block vs Inline Elements
**Current Description:**
> "HTML elements fall into two main categories: Block elements (containers) start on a new line and take full width. Examples: div, p, h1, section. Inline elements flow within text and only take needed width. Examples: span, a, strong, em"
**Issues:**
- No "why" context - why does HTML distinguish between block and inline?
- No historical context
- No practical application explanation
**Improved Description:**
```
<strong>Understanding Document Flow</strong><br><br>
When browsers render HTML, they follow a concept called <em>document flow</em> - the natural way elements arrange themselves on a page. This fundamental concept, dating back to HTML's origins as a document markup language, divides elements into two categories:<br><br>
<strong>Block elements</strong> behave like paragraphs in a word processor - they start on a new line and stretch to fill available width. Think of them as "containers" that stack vertically. Examples: <kbd>&lt;div&gt;</kbd>, <kbd>&lt;p&gt;</kbd>, <kbd>&lt;h1&gt;</kbd>, <kbd>&lt;section&gt;</kbd><br><br>
<strong>Inline elements</strong> behave like words in a sentence - they flow within text without breaking the line, taking only the width they need. Examples: <kbd>&lt;span&gt;</kbd>, <kbd>&lt;a&gt;</kbd>, <kbd>&lt;strong&gt;</kbd>, <kbd>&lt;em&gt;</kbd><br><br>
<strong>Why this matters:</strong> Understanding block vs inline is essential for CSS layout. You cannot set width/height on inline elements, and vertical margins behave differently. This distinction forms the foundation of all web layout.
```
#### Lesson 2: Semantic Tags
**Current Description:** Good, but could add brief "why" for accessibility
**Add to beginning:**
```
Semantic HTML helps both browsers and assistive technologies (like screen readers) understand your content structure. Using the right semantic elements improves accessibility and SEO.<br><br>
```
#### Lesson 3: div & span
**Action:** REMOVE (redundant - block/inline already covered in lesson 1)
---
### Module: HTML Forms - Basics (21-html-forms-basic.json)
#### Lesson 1: Form Structure
**Current Description:**
> "Every form needs a form wrapper. Inside, use label to describe inputs and input for user data entry. The for attribute on labels should match the id on inputs for accessibility."
**Issues:**
- No context about what forms ARE or why they exist
- No mention of HTTP form submission
**Improved Description:**
```
<strong>HTML forms are the primary way users send data to websites</strong> - from login credentials to search queries to payment information. Without forms, the web would be read-only.<br><br>
Every form needs a <kbd>&lt;form&gt;</kbd> wrapper that defines where data goes when submitted. Inside, you build the interface with:<br><br>
• <kbd>&lt;label&gt;</kbd> - Describes what each input is for<br>
• <kbd>&lt;input&gt;</kbd> - Where users enter data<br><br>
<strong>Accessibility tip:</strong> The <kbd>for</kbd> attribute on labels should match the <kbd>id</kbd> on inputs. This lets users click the label to focus the input - essential for users with motor impairments.
```
#### Lesson 2: Input Types
**Status:** Good as-is (score 24/25)
#### Lesson 3: Submit Button
**Current Description:** Good but could be briefer (this is lesson 3)
**Action:** Reduce slightly - appropriate for late-module position
---
### Module: HTML Forms - Validation (22-html-forms-validation.json)
#### Lesson 3: Full Form (Complete Registration)
**Current Task:**
> "Complete the registration form. Add required attributes, proper input types, and validation constraints."
**Issue:** Task is vague - doesn't specify exactly what to add
**Improved Task:**
```
Complete the registration form by adding:<br>
1. <kbd>required</kbd> to all fields marked with *<br>
2. <kbd>type="email"</kbd> to the email input<br>
3. <kbd>type="password"</kbd> to the password input<br>
4. <kbd>minlength="8"</kbd> to the password input<br>
5. <kbd>required</kbd> to the terms checkbox
```
---
### Module: HTML Details & Summary (23-html-details-summary.json)
#### Lesson 1: First Widget
**Add to description beginning:**
```
Before HTML5, creating collapsible content required JavaScript. The <kbd>&lt;details&gt;</kbd> element gives you this functionality natively - no scripts needed, fully accessible, works everywhere.<br><br>
```
---
### Module: HTML Tables (30-html-tables.json)
#### Lesson 1: Basic Table Structure
**Add to description beginning:**
```
<strong>Important:</strong> Tables are for <em>tabular data</em> only (like spreadsheets, schedules, or comparison charts). Never use tables for page layout - that's what CSS Grid and Flexbox are for.<br><br>
```
---
### Module: HTML SVG (32-html-svg.json)
#### Lesson 1: Drawing Circles
**Add to description beginning:**
```
<strong>SVG (Scalable Vector Graphics)</strong> creates images using mathematical descriptions rather than pixels. Unlike JPG or PNG, SVG images stay crisp at any size - perfect for logos, icons, and illustrations.<br><br>
```
---
## CSS Section Lessons
### Module: CSS Selectors (00-basic-selectors.json)
**Status:** EXCELLENT - Use as template for other modules. No changes needed.
---
### Module: CSS Box Model (01-box-model.json)
#### Lesson 1: Box Model Components
**Current Description:**
> "The CSS box model consists of four concentric layers: content area (innermost), padding, border, and margin (outermost). Understanding how these components interact is essential for precise layout control."
**Issues:**
- Good but could be more comprehensive like CSS Selectors lesson 1
**Improved Description:**
```
<strong>The CSS box model is the foundation of all web layout.</strong> Every HTML element is rendered as a rectangular box, and understanding this box is crucial for controlling spacing and sizing.<br><br>
The box model consists of four concentric layers (from inside out):<br>
1. <strong>Content</strong> - Your actual text, images, or nested elements<br>
2. <strong>Padding</strong> - Space between content and border (inside the element)<br>
3. <strong>Border</strong> - The visible edge of the element<br>
4. <strong>Margin</strong> - Space between this element and others (outside the element)<br><br>
<pre>.box {
/* Content is determined by width/height */
padding: 20px; /* Inside spacing */
border: 2px solid black;
margin: 10px; /* Outside spacing */
}</pre>
<strong>Key insight:</strong> Padding adds to the element's visual size; margin creates empty space around it.
```
---
### Module: CSS Flexbox (flexbox.json) - CRITICAL
#### Lesson 1: Container
**Current Description:**
> "Learn how to create a flex container and understand the main and cross axes.
> [code block]"
**Issues:**
- ONLY 2 sentences before code block!
- No "why" context
- No comparison to older methods
- No explanation of when to use flexbox
**Improved Description:**
```
<strong>Flexbox revolutionized CSS layout.</strong> Before flexbox (2012), developers used floats and positioning hacks for layouts - techniques that were never designed for that purpose. Flexbox was created specifically to solve common layout problems.<br><br>
<strong>When to use Flexbox:</strong><br>
• Centering content (finally easy!)<br>
• Distributing space between items<br>
• Aligning items in a row or column<br>
• Creating responsive navigation bars<br>
• Building card layouts<br><br>
<strong>The two axes:</strong><br>
Flexbox works along two perpendicular axes:<br>
• <strong>Main axis</strong> - The direction items flow (horizontal by default)<br>
• <strong>Cross axis</strong> - Perpendicular to main axis (vertical by default)<br><br>
<pre>.container {
display: flex; /* Creates flex container */
justify-content: center; /* Align on main axis */
align-items: center; /* Align on cross axis */
}</pre>
To start, you only need <kbd>display: flex</kbd> on the parent container. This immediately makes all direct children "flex items" that can be aligned and distributed.
```
#### Lessons 2-6
**Status:** Good as-is - appropriately brief for later lessons
---
### Module: CSS Responsive Design (08-responsive.json)
#### Lesson 1: Media Queries
**Add to description beginning:**
```
<strong>Responsive design</strong> means your layout adapts to different screen sizes - from phones to desktops. Media queries are CSS rules that only apply when certain conditions (like screen width) are met.<br><br>
```
---
### Module: CSS Animations (06-transitions-animations.json)
#### Lesson 1: Transitions
**Add to description:**
```
<strong>UX principle:</strong> Animations should enhance usability, not distract. Use subtle, fast transitions (0.2-0.3s) for interactive feedback. Reserve longer animations for meaningful state changes.<br><br>
```
---
## Unused Modules to Add
### Module: CSS Colors (03-colors.json)
#### Lesson 1: Setting Background Colors
**Current Issues:**
- Uses hex code (#e0f7fa) instead of named color
- No context about color accessibility
**Improved Description:**
```
<strong>Color is fundamental to web design</strong>, but it's also one of the most important accessibility considerations. Approximately 8% of men have some form of color blindness.<br><br>
CSS offers multiple ways to specify colors:<br>
• <strong>Named colors:</strong> <kbd>steelblue</kbd>, <kbd>coral</kbd>, <kbd>gold</kbd> (147 names)<br>
• <strong>Hex codes:</strong> <kbd>#3498db</kbd> (harder to read)<br>
• <strong>RGB:</strong> <kbd>rgb(52, 152, 219)</kbd><br>
• <strong>HSL:</strong> <kbd>hsl(204, 70%, 53%)</kbd> (easiest to adjust)<br><br>
For learning, we'll use named colors - they're memorable and readable.
```
**Fix task:** Change `#e0f7fa` to `lightcyan` (equivalent named color)
#### Lesson 4: Background Images
**Current Task:** "Set a background image on '.bg-img' using a placeholder URL, center it, and prevent tiling."
**Issue:** Vague - what URL? What values?
**Improved Task:**
```
The background image is already set. Add these properties to <kbd>.bg-img</kbd>:<br>
1. <kbd>background-position: center</kbd><br>
2. <kbd>background-repeat: no-repeat</kbd>
```
---
### Module: CSS Typography (04-typography.json)
#### Lesson 1: Font Family & Fallbacks
**Add context:**
```
<strong>Web fonts vs System fonts:</strong> Web fonts (like Google Fonts) load from the internet, adding download time. System fonts (like Georgia, Arial) are already on users' devices - instant and reliable.<br><br>
<strong>Fallback stacks</strong> ensure text displays even if your preferred font fails to load. Always end with a generic family (<kbd>serif</kbd>, <kbd>sans-serif</kbd>, <kbd>monospace</kbd>).
```
#### Lesson 4: Text Decoration & Shadow
**Current Task:** "Apply an underline with text-decoration and a light shadow using text-shadow on '.fancy'."
**Issue:** Doesn't specify shadow values
**Improved Task:**
```
Style <kbd>.fancy</kbd> with:<br>
1. <kbd>text-decoration: underline</kbd><br>
2. <kbd>text-shadow: 1px 1px 2px gray</kbd>
```
---
### Module: CSS Grid (grid.json)
#### Lesson 1: Grid Container Basics
**Add context about Grid vs Flexbox:**
```
<strong>Grid vs Flexbox - when to use which?</strong><br><br>
• <strong>Flexbox:</strong> One-dimensional layouts (a row OR a column)<br>
• <strong>Grid:</strong> Two-dimensional layouts (rows AND columns together)<br><br>
Use Grid when you need to align items in both directions simultaneously - like a photo gallery, dashboard, or page layout. Use Flexbox for navigation bars, card rows, or centering content.<br><br>
Grid was the last major layout feature added to CSS (2017), completing the layout toolkit that web designers had wanted for decades.
```
---
# Summary: Lessons Requiring Changes
| Module | Lesson | Change Type | Priority |
|--------|--------|-------------|----------|
| HTML Block & Inline | 1. Block vs Inline | Rewrite description | HIGH |
| HTML Block & Inline | 2. Semantic Tags | Add accessibility context | MEDIUM |
| HTML Block & Inline | 3. div & span | **REMOVE** | HIGH |
| HTML Forms | 1. Form Structure | Enhance description | MEDIUM |
| HTML Forms Validation | 3. Full Form | Clarify task | MEDIUM |
| HTML Details | 1. First Widget | Add history context | LOW |
| HTML Tables | 1. Basic Table | Add "not for layout" warning | MEDIUM |
| HTML SVG | 1. Drawing Circles | Add SVG vs raster context | LOW |
| CSS Box Model | 1. Components | Enhance description | MEDIUM |
| **CSS Flexbox** | **1. Container** | **REWRITE description** | **CRITICAL** |
| CSS Responsive | 1. Media Queries | Add responsive context | LOW |
| CSS Animations | 1. Transitions | Add UX principle | LOW |
| CSS Colors | 1. Background Colors | Fix hexnamed, add a11y | MEDIUM |
| CSS Colors | 4. Background Images | Clarify task | MEDIUM |
| CSS Typography | 1. Font Family | Add web font context | MEDIUM |
| CSS Typography | 4. Decoration | Specify shadow values | MEDIUM |
| CSS Grid | 1. Container Basics | Add Grid vs Flexbox | MEDIUM |

View File

@@ -1,119 +1,87 @@
{
"$schema": "../schemas/code-crispies-module-schema.json",
"id": "colors-backgrounds",
"title": "Colors",
"description": "Learn how to apply and manipulate colors, backgrounds, and graphical fills using CSS properties.",
"title": "CSS Colors",
"description": "Learn how to apply colors to text and backgrounds using CSS properties.",
"difficulty": "beginner",
"lessons": [
{
"id": "colors-1",
"title": "Setting Background Colors",
"description": "Use the <code>background-color</code> property to fill elements with solid colors.",
"task": "Apply a light cyan background (#e0f7fa) to the element with class 'colorbox'.",
"previewHTML": "<div class=\"colorbox\">Background Demo</div>",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .colorbox { padding: 1rem; }",
"title": "Background Color",
"description": "Color is one of the most powerful tools in web design. It creates visual hierarchy, conveys meaning, and establishes brand identity. CSS provides multiple ways to specify colors.<br><br><strong>CSS named colors:</strong> CSS includes 147 named colors like <kbd>steelblue</kbd>, <kbd>coral</kbd>, <kbd>gold</kbd>, and <kbd>tomato</kbd>. These are easy to remember and read.<br><br><strong>The background-color property:</strong> Sets the fill color behind an element's content and padding areas. The color extends to the edge of the element's border.<br><br><pre>.box {\n background-color: lightblue;\n}</pre>",
"task": "Set <kbd>background-color</kbd> to <kbd>lightcyan</kbd> on <kbd>.box</kbd>.",
"previewHTML": "<div class=\"box\">Background Demo</div>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .box { padding: 1rem; border: 2px solid steelblue; }",
"sandboxCSS": "",
"codePrefix": "/* Set a background color */\n.colorbox {",
"codePrefix": ".box {\n ",
"initialCode": "",
"codeSuffix": "}",
"codeSuffix": "\n}",
"previewContainer": "preview-area",
"validations": [
{ "type": "contains", "value": ".colorbox", "message": "Select <kbd>.colorbox</kbd>", "options": { "caseSensitive": false } },
{
"type": "contains",
"value": "background-color",
"message": "Use <kbd>background-color</kbd> property",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "background-color", "expected": "#e0f7fa" },
"message": "Set background-color to <kbd>#e0f7fa</kbd>",
"options": { "exact": true }
"value": { "property": "background-color", "expected": "lightcyan" },
"message": "Set <kbd>background-color: lightcyan</kbd>"
}
]
},
{
"id": "colors-2",
"title": "Text Color and Contrast",
"description": "Apply the <code>color</code> property to control text readability against backgrounds.",
"task": "Set the text color of '.colorbox' to deep blue (#01579b). Ensure good contrast.",
"previewHTML": "<div class=\"colorbox\">Color & Contrast</div>",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .colorbox { padding: 1rem; background: #e0f7fa; }",
"title": "Text Color",
"description": "The <kbd>color</kbd> property sets the color of text content. Good contrast between text and background is essential for readability.",
"task": "Set <kbd>color</kbd> to <kbd>darkslategray</kbd> on <kbd>.box</kbd>.",
"previewHTML": "<div class=\"box\">Color & Contrast</div>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .box { padding: 1rem; background-color: lightcyan; border: 2px solid steelblue; }",
"sandboxCSS": "",
"codePrefix": "/* Set text color */\n.colorbox {",
"codePrefix": ".box {\n ",
"initialCode": "",
"codeSuffix": "}",
"codeSuffix": "\n}",
"previewContainer": "preview-area",
"validations": [
{ "type": "contains", "value": ".colorbox", "message": "Select <kbd>.colorbox</kbd>", "options": { "caseSensitive": false } },
{ "type": "contains", "value": "color", "message": "Use the <kbd>color</kbd> property", "options": { "caseSensitive": false } },
{
"type": "property_value",
"value": { "property": "color", "expected": "#01579b" },
"message": "Set color to <kbd>#01579b</kbd>",
"options": { "exact": true }
"value": { "property": "color", "expected": "darkslategray" },
"message": "Set <kbd>color: darkslategray</kbd>"
}
]
},
{
"id": "colors-3",
"title": "CSS Gradients",
"description": "Learn to create smooth transitions between colors using linear and radial gradients.",
"task": "Apply a linear gradient background from #ff9a9e to #fad0c4 on an element with class 'gradient-box'.",
"previewHTML": "<div class=\"gradient-box\">Gradient Demo</div>",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .gradient-box { padding: 1rem; color: white; text-align: center; }",
"title": "Border Color",
"description": "Borders can have their own color using <kbd>border-color</kbd>, or you can specify color in the border shorthand.",
"task": "Set <kbd>border-color</kbd> to <kbd>coral</kbd> on <kbd>.box</kbd>.",
"previewHTML": "<div class=\"box\">Border Color</div>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .box { padding: 1rem; background-color: seashell; border: 4px solid gray; }",
"sandboxCSS": "",
"codePrefix": "/* Set a linear gradient background */\n.gradient-box {",
"codePrefix": ".box {\n ",
"initialCode": "",
"codeSuffix": "}",
"codeSuffix": "\n}",
"previewContainer": "preview-area",
"validations": [
{ "type": "contains", "value": ".gradient-box", "message": "Select <kbd>.gradient-box</kbd>", "options": { "caseSensitive": false } },
{
"type": "contains",
"value": "background-image",
"message": "Use <kbd>background-image</kbd> property",
"options": { "caseSensitive": false }
},
{
"type": "regex",
"value": "linear-gradient\\(.*#ff9a9e.*,.*#fad0c4.*\\)",
"message": "Use <kbd>linear-gradient</kbd> from <kbd>#ff9a9e</kbd> to <kbd>#fad0c4</kbd>",
"options": { "caseSensitive": false }
"type": "property_value",
"value": { "property": "border-color", "expected": "coral" },
"message": "Set <kbd>border-color: coral</kbd>"
}
]
},
{
"id": "colors-4",
"title": "Background Images & Repeat",
"description": "Add images as backgrounds and control repetition and positioning.",
"task": "Set a background image on '.bg-img' using a placeholder URL, center it, and prevent tiling.",
"previewHTML": "<div class=\"bg-img\">Image Background</div>",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .bg-img { height: 150px; display: flex; align-items: center; justify-content: center; color: white; }",
"title": "Color Formats",
"description": "Besides named colors, CSS supports hex codes (<kbd>#ff6347</kbd>), RGB (<kbd>rgb(255, 99, 71)</kbd>), and HSL (<kbd>hsl(9, 100%, 64%)</kbd>) formats.",
"task": "Set <kbd>background-color</kbd> to <kbd>#f0e68c</kbd> (khaki in hex) on <kbd>.box</kbd>.",
"previewHTML": "<div class=\"box\">Hex Color</div>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .box { padding: 1rem; border: 2px solid olive; }",
"sandboxCSS": "",
"codePrefix": "/* Set background image */\n\n.bg-img {",
"initialCode": " background-image: url('http://placekitten.com/320/320');\n background-position: center; background-repeat: no-repeat;\n ",
"codeSuffix": "}",
"codePrefix": ".box {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"previewContainer": "preview-area",
"validations": [
{
"type": "contains",
"value": "background-image",
"message": "Use <kbd>background-image</kbd> property",
"options": { "caseSensitive": false }
},
{
"type": "contains",
"value": "background-position: center",
"message": "Center the background image with <kbd>background-position: center</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "contains",
"value": "background-repeat: no-repeat",
"message": "Prevent image tiling with <kbd>background-repeat: no-repeat</kbd>",
"options": { "caseSensitive": false }
"type": "property_value",
"value": { "property": "background-color", "expected": "#f0e68c" },
"message": "Set <kbd>background-color: #f0e68c</kbd>"
}
]
}

View File

@@ -63,35 +63,6 @@
"message": "Add an <kbd>&lt;h1&gt;</kbd> heading inside your header"
}
]
},
{
"id": "div-vs-span",
"title": "div & span",
"description": "When you need a container without semantic meaning:<br><br><kbd>&lt;div&gt;</kbd> - Generic block container (for layout/grouping)<br><kbd>&lt;span&gt;</kbd> - Generic inline container (for styling text portions)<br><br>Use semantic elements when possible, div/span when no semantic element fits.",
"task": "Wrap the word 'highlighted' in a <kbd>&lt;span&gt;</kbd> to style it differently. Wrap the whole quote in a <kbd>&lt;div&gt;</kbd>.",
"previewHTML": "",
"previewBaseCSS": "body { font-family: Georgia, serif; padding: 20px; } div { background: #f5f5f5; padding: 15px; border-left: 4px solid #1976d2; } span { background: #fff59d; padding: 2px 4px; }",
"sandboxCSS": "",
"initialCode": "The most highlighted moment was unforgettable.",
"solution": "<div>The most <span>highlighted</span> moment was unforgettable.</div>",
"previewContainer": "preview-area",
"validations": [
{
"type": "element_exists",
"value": "div",
"message": "Wrap everything in a <kbd>&lt;div&gt;</kbd> element"
},
{
"type": "element_exists",
"value": "span",
"message": "Add a <kbd>&lt;span&gt;</kbd> around the word <kbd>highlighted</kbd>"
},
{
"type": "element_text",
"value": { "selector": "span", "text": "highlighted" },
"message": "The <kbd>&lt;span&gt;</kbd> should contain the word <kbd>highlighted</kbd>"
}
]
}
]
}

View File

@@ -63,35 +63,6 @@
"message": "Add an <kbd>&lt;h1&gt;</kbd> heading inside your header"
}
]
},
{
"id": "div-vs-span",
"title": "div & span",
"description": "When you need a container without semantic meaning:<br><br><kbd>&lt;div&gt;</kbd> - Generic block container (for layout/grouping)<br><kbd>&lt;span&gt;</kbd> - Generic inline container (for styling text portions)<br><br>Use semantic elements when possible, div/span when no semantic element fits.",
"task": "Wrap the word 'highlighted' in a <kbd>&lt;span&gt;</kbd> to style it differently. Wrap the whole quote in a <kbd>&lt;div&gt;</kbd>.",
"previewHTML": "",
"previewBaseCSS": "body { font-family: Georgia, serif; padding: 20px; } div { background: #f5f5f5; padding: 15px; border-left: 4px solid #1976d2; } span { background: #fff59d; padding: 2px 4px; }",
"sandboxCSS": "",
"initialCode": "The most highlighted moment was unforgettable.",
"solution": "<div>The most <span>highlighted</span> moment was unforgettable.</div>",
"previewContainer": "preview-area",
"validations": [
{
"type": "element_exists",
"value": "div",
"message": "Wrap everything in a <kbd>&lt;div&gt;</kbd> element"
},
{
"type": "element_exists",
"value": "span",
"message": "Add a <kbd>&lt;span&gt;</kbd> around the word <kbd>highlighted</kbd>"
},
{
"type": "element_text",
"value": { "selector": "span", "text": "highlighted" },
"message": "The <kbd>&lt;span&gt;</kbd> should contain the word <kbd>highlighted</kbd>"
}
]
}
]
}

View File

@@ -63,35 +63,6 @@
"message": "Füge eine <kbd>&lt;h1&gt;</kbd>-Überschrift in deinem Header hinzu"
}
]
},
{
"id": "div-vs-span",
"title": "Generische Container: div und span",
"description": "Wenn du einen Container ohne semantische Bedeutung benötigst:<br><br><kbd>&lt;div&gt;</kbd> - Generischer Block-Container (für Layout/Gruppierung)<br><kbd>&lt;span&gt;</kbd> - Generischer Inline-Container (zum Stylen von Textteilen)<br><br>Verwende semantische Elemente wenn möglich, div/span wenn kein semantisches Element passt.",
"task": "Umschließe das Wort 'hervorgehoben' mit einem <kbd>&lt;span&gt;</kbd>, um es anders zu gestalten. Umschließe das gesamte Zitat mit einem <kbd>&lt;div&gt;</kbd>.",
"previewHTML": "",
"previewBaseCSS": "body { font-family: Georgia, serif; padding: 20px; } div { background: #f5f5f5; padding: 15px; border-left: 4px solid #1976d2; } span { background: #fff59d; padding: 2px 4px; }",
"sandboxCSS": "",
"initialCode": "Der hervorgehoben Moment war unvergesslich.",
"solution": "<div>Der <span>hervorgehoben</span> Moment war unvergesslich.</div>",
"previewContainer": "preview-area",
"validations": [
{
"type": "element_exists",
"value": "div",
"message": "Umschließe alles mit einem <kbd>&lt;div&gt;</kbd>-Element"
},
{
"type": "element_exists",
"value": "span",
"message": "Füge ein <kbd>&lt;span&gt;</kbd> um das Wort 'hervorgehoben' hinzu"
},
{
"type": "element_text",
"value": { "selector": "span", "text": "hervorgehoben" },
"message": "Das <kbd>&lt;span&gt;</kbd> sollte das Wort 'hervorgehoben' enthalten"
}
]
}
]
}

View File

@@ -63,35 +63,6 @@
"message": "Add an <kbd>&lt;h1&gt;</kbd> heading inside your header"
}
]
},
{
"id": "div-vs-span",
"title": "div & span",
"description": "When you need a container without semantic meaning:<br><br><kbd>&lt;div&gt;</kbd> - Generic block container (for layout/grouping)<br><kbd>&lt;span&gt;</kbd> - Generic inline container (for styling text portions)<br><br>Use semantic elements when possible, div/span when no semantic element fits.",
"task": "Wrap the word 'highlighted' in a <kbd>&lt;span&gt;</kbd> to style it differently. Wrap the whole quote in a <kbd>&lt;div&gt;</kbd>.",
"previewHTML": "",
"previewBaseCSS": "body { font-family: Georgia, serif; padding: 20px; } div { background: #f5f5f5; padding: 15px; border-left: 4px solid #1976d2; } span { background: #fff59d; padding: 2px 4px; }",
"sandboxCSS": "",
"initialCode": "The most highlighted moment was unforgettable.",
"solution": "<div>The most <span>highlighted</span> moment was unforgettable.</div>",
"previewContainer": "preview-area",
"validations": [
{
"type": "element_exists",
"value": "div",
"message": "Wrap everything in a <kbd>&lt;div&gt;</kbd> element"
},
{
"type": "element_exists",
"value": "span",
"message": "Add a <kbd>&lt;span&gt;</kbd> around the word <kbd>highlighted</kbd>"
},
{
"type": "element_text",
"value": { "selector": "span", "text": "highlighted" },
"message": "The <kbd>&lt;span&gt;</kbd> should contain the word <kbd>highlighted</kbd>"
}
]
}
]
}

View File

@@ -8,8 +8,8 @@
{
"id": "flexbox-1",
"title": "Container",
"description": "Learn how to create a flex container and understand the main and cross axes.<br><br><pre>.container {\n display: flex;\n justify-content: center;\n align-items: center;\n}</pre>",
"task": "Add <kbd>display: flex</kbd> to <kbd>.wrap</kbd> to create a flexbox layout.",
"description": "Before flexbox, creating even simple layouts required floats, positioning hacks, or table-based layouts. Flexbox (Flexible Box Layout) revolutionized CSS by providing a one-dimensional layout system designed specifically for distributing space and aligning content.<br><br><strong>How it works:</strong> When you set <kbd>display: flex</kbd> on an element, it becomes a <em>flex container</em>. Its direct children automatically become <em>flex items</em> that flow along a main axis (horizontal by default). This single property transforms stacked block elements into a horizontal row.<br><br><strong>The two axes:</strong><br>• <em>Main axis</em> The primary direction items flow (row = left→right)<br>• <em>Cross axis</em> Perpendicular to main (row = top→bottom)<br><br><pre>.container {\n display: flex;\n /* Items now flow horizontally */\n}</pre>",
"task": "Add <kbd>display: flex</kbd> to <kbd>.wrap</kbd> to arrange the boxes horizontally.",
"previewHTML": "<div class='wrap'><div class='box'>1</div><div class='box'>2</div><div class='box'>3</div></div>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .box { background: steelblue; color: white; padding: 1rem; margin: 8px; text-align: center; font-weight: bold; }",
"sandboxCSS": ".wrap { border: 2px dashed #aaa; padding: 1rem; }",

View File

@@ -1,15 +1,15 @@
{
"$schema": "../schemas/code-crispies-module-schema.json",
"id": "grid",
"title": "Grid",
"title": "CSS Grid",
"description": "Master the grid layout system for complex two-dimensional layouts",
"difficulty": "intermediate",
"lessons": [
{
"id": "grid-1",
"title": "Grid Container Basics",
"description": "Learn how to create a grid container and define basic grid structures.<br><br><pre>.container {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 1rem;\n}</pre>",
"task": "Create a <kbd>.grid</kbd> with <kbd>display: grid</kbd>, <kbd>grid-template-columns: repeat(3, 1fr)</kbd>, and <kbd>gap: 1rem</kbd>.",
"title": "Grid Container",
"description": "CSS Grid is a two-dimensional layout system, meaning it can handle both columns AND rows simultaneously. While Flexbox excels at one-dimensional layouts (a single row or column), Grid shines when you need precise control over both dimensions.<br><br><strong>How it works:</strong> Set <kbd>display: grid</kbd> on a container. Then define your column structure with <kbd>grid-template-columns</kbd>. The <kbd>fr</kbd> unit represents a fraction of available space.<br><br><strong>Key properties:</strong><br>• <kbd>grid-template-columns</kbd> Defines column sizes<br>• <kbd>repeat(3, 1fr)</kbd> Creates 3 equal columns<br>• <kbd>gap</kbd> Adds spacing between grid cells<br><br><pre>.grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 1rem;\n}</pre>",
"task": "Add <kbd>display: grid</kbd>, <kbd>grid-template-columns: repeat(3, 1fr)</kbd>, and <kbd>gap: 1rem</kbd> to <kbd>.grid</kbd>.",
"previewHTML": "<div class='grid'><div class='item'>1</div><div class='item'>2</div><div class='item'>3</div><div class='item'>4</div><div class='item'>5</div><div class='item'>6</div></div>",
"previewBaseCSS": "body { font-family: system-ui, -apple-system, sans-serif; padding: 1.25rem; } .item { background-color: #9b59b6; color: white; padding: 1.25rem; text-align: center; font-weight: bold; }",
"sandboxCSS": ".grid { border: 0.125rem dashed #ccc; padding: 1rem; }",

View File

@@ -63,35 +63,6 @@
"message": "Add an <kbd>&lt;h1&gt;</kbd> heading inside your header"
}
]
},
{
"id": "div-vs-span",
"title": "div & span",
"description": "When you need a container without semantic meaning:<br><br><kbd>&lt;div&gt;</kbd> - Generic block container (for layout/grouping)<br><kbd>&lt;span&gt;</kbd> - Generic inline container (for styling text portions)<br><br>Use semantic elements when possible, div/span when no semantic element fits.",
"task": "Wrap the word 'highlighted' in a <kbd>&lt;span&gt;</kbd> to style it differently. Wrap the whole quote in a <kbd>&lt;div&gt;</kbd>.",
"previewHTML": "",
"previewBaseCSS": "body { font-family: Georgia, serif; padding: 20px; } div { background: #f5f5f5; padding: 15px; border-left: 4px solid #1976d2; } span { background: #fff59d; padding: 2px 4px; }",
"sandboxCSS": "",
"initialCode": "The most highlighted moment was unforgettable.",
"solution": "<div>The most <span>highlighted</span> moment was unforgettable.</div>",
"previewContainer": "preview-area",
"validations": [
{
"type": "element_exists",
"value": "div",
"message": "Wrap everything in a <kbd>&lt;div&gt;</kbd> element"
},
{
"type": "element_exists",
"value": "span",
"message": "Add a <kbd>&lt;span&gt;</kbd> around the word <kbd>highlighted</kbd>"
},
{
"type": "element_text",
"value": { "selector": "span", "text": "highlighted" },
"message": "The <kbd>&lt;span&gt;</kbd> should contain the word <kbd>highlighted</kbd>"
}
]
}
]
}

View File

@@ -63,35 +63,6 @@
"message": "Add an <kbd>&lt;h1&gt;</kbd> heading inside your header"
}
]
},
{
"id": "div-vs-span",
"title": "div & span",
"description": "When you need a container without semantic meaning:<br><br><kbd>&lt;div&gt;</kbd> - Generic block container (for layout/grouping)<br><kbd>&lt;span&gt;</kbd> - Generic inline container (for styling text portions)<br><br>Use semantic elements when possible, div/span when no semantic element fits.",
"task": "Wrap the word 'highlighted' in a <kbd>&lt;span&gt;</kbd> to style it differently. Wrap the whole quote in a <kbd>&lt;div&gt;</kbd>.",
"previewHTML": "",
"previewBaseCSS": "body { font-family: Georgia, serif; padding: 20px; } div { background: #f5f5f5; padding: 15px; border-left: 4px solid #1976d2; } span { background: #fff59d; padding: 2px 4px; }",
"sandboxCSS": "",
"initialCode": "The most highlighted moment was unforgettable.",
"solution": "<div>The most <span>highlighted</span> moment was unforgettable.</div>",
"previewContainer": "preview-area",
"validations": [
{
"type": "element_exists",
"value": "div",
"message": "Wrap everything in a <kbd>&lt;div&gt;</kbd> element"
},
{
"type": "element_exists",
"value": "span",
"message": "Add a <kbd>&lt;span&gt;</kbd> around the word <kbd>highlighted</kbd>"
},
{
"type": "element_text",
"value": { "selector": "span", "text": "highlighted" },
"message": "The <kbd>&lt;span&gt;</kbd> should contain the word <kbd>highlighted</kbd>"
}
]
}
]
}

View File

@@ -6,7 +6,10 @@
// English lesson imports
import welcomeEN from "../../lessons/00-welcome.json";
import basicSelectorsEN from "../../lessons/00-basic-selectors.json";
import advancedSelectorsEN from "../../lessons/01-advanced-selectors.json";
import boxModelEN from "../../lessons/01-box-model.json";
import colorsEN from "../../lessons/03-colors.json";
import typographyEN from "../../lessons/04-typography.json";
import unitsVariablesEN from "../../lessons/05-units-variables.json";
import transitionsAnimationsEN from "../../lessons/06-transitions-animations.json";
import responsiveEN from "../../lessons/08-responsive.json";
@@ -16,9 +19,9 @@ import htmlFormsValidationEN from "../../lessons/22-html-forms-validation.json";
import htmlDetailsSummaryEN from "../../lessons/23-html-details-summary.json";
import htmlProgressMeterEN from "../../lessons/24-html-progress-meter.json";
import htmlTablesEN from "../../lessons/30-html-tables.json";
import htmlMarqueeEN from "../../lessons/31-html-marquee.json";
import htmlSvgEN from "../../lessons/32-html-svg.json";
import flexboxEN from "../../lessons/flexbox.json";
import gridEN from "../../lessons/grid.json";
import goodbyeEN from "../../lessons/99-goodbye.json";
// German lesson imports
@@ -34,7 +37,6 @@ import htmlFormsValidationDE from "../../lessons/de/22-html-forms-validation.jso
import htmlDetailsSummaryDE from "../../lessons/de/23-html-details-summary.json";
import htmlProgressMeterDE from "../../lessons/de/24-html-progress-meter.json";
import htmlTablesDE from "../../lessons/de/30-html-tables.json";
import htmlMarqueeDE from "../../lessons/de/31-html-marquee.json";
import htmlSvgDE from "../../lessons/de/32-html-svg.json";
import flexboxDE from "../../lessons/de/flexbox.json";
@@ -51,7 +53,6 @@ import htmlFormsValidationPL from "../../lessons/pl/22-html-forms-validation.jso
import htmlDetailsSummaryPL from "../../lessons/pl/23-html-details-summary.json";
import htmlProgressMeterPL from "../../lessons/pl/24-html-progress-meter.json";
import htmlTablesPL from "../../lessons/pl/30-html-tables.json";
import htmlMarqueePL from "../../lessons/pl/31-html-marquee.json";
import htmlSvgPL from "../../lessons/pl/32-html-svg.json";
import flexboxPL from "../../lessons/pl/flexbox.json";
@@ -68,7 +69,6 @@ import htmlFormsValidationES from "../../lessons/es/22-html-forms-validation.jso
import htmlDetailsSummaryES from "../../lessons/es/23-html-details-summary.json";
import htmlProgressMeterES from "../../lessons/es/24-html-progress-meter.json";
import htmlTablesES from "../../lessons/es/30-html-tables.json";
import htmlMarqueeES from "../../lessons/es/31-html-marquee.json";
import htmlSvgES from "../../lessons/es/32-html-svg.json";
import flexboxES from "../../lessons/es/flexbox.json";
@@ -85,7 +85,6 @@ import htmlFormsValidationAR from "../../lessons/ar/22-html-forms-validation.jso
import htmlDetailsSummaryAR from "../../lessons/ar/23-html-details-summary.json";
import htmlProgressMeterAR from "../../lessons/ar/24-html-progress-meter.json";
import htmlTablesAR from "../../lessons/ar/30-html-tables.json";
import htmlMarqueeAR from "../../lessons/ar/31-html-marquee.json";
import htmlSvgAR from "../../lessons/ar/32-html-svg.json";
import flexboxAR from "../../lessons/ar/flexbox.json";
@@ -102,7 +101,6 @@ import htmlFormsValidationUK from "../../lessons/uk/22-html-forms-validation.jso
import htmlDetailsSummaryUK from "../../lessons/uk/23-html-details-summary.json";
import htmlProgressMeterUK from "../../lessons/uk/24-html-progress-meter.json";
import htmlTablesUK from "../../lessons/uk/30-html-tables.json";
import htmlMarqueeUK from "../../lessons/uk/31-html-marquee.json";
import htmlSvgUK from "../../lessons/uk/32-html-svg.json";
import flexboxUK from "../../lessons/uk/flexbox.json";
@@ -110,25 +108,29 @@ import flexboxUK from "../../lessons/uk/flexbox.json";
const moduleStoreEN = [
// Welcome
welcomeEN,
// HTML Grundlagen
// HTML Fundamentals
htmlElementsEN,
htmlFormsBasicEN,
htmlFormsValidationEN,
// HTML Interaktiv
// HTML Interactive
htmlDetailsSummaryEN,
htmlProgressMeterEN,
// HTML Weitere
// HTML Data
htmlTablesEN,
htmlSvgEN,
htmlMarqueeEN,
// CSS Grundlagen
// CSS Fundamentals
basicSelectorsEN,
advancedSelectorsEN,
colorsEN,
typographyEN,
boxModelEN,
unitsVariablesEN,
// CSS Graphics
htmlSvgEN,
// CSS Layouts
flexboxEN,
gridEN,
responsiveEN,
// CSS Animationen
// CSS Animation
transitionsAnimationsEN,
// Goodbye
goodbyeEN
@@ -138,25 +140,29 @@ const moduleStoreEN = [
const moduleStoreDE = [
// Welcome
welcomeDE,
// HTML Grundlagen
// HTML Fundamentals
htmlElementsDE,
htmlFormsBasicDE,
htmlFormsValidationDE,
// HTML Interaktiv
// HTML Interactive
htmlDetailsSummaryDE,
htmlProgressMeterDE,
// HTML Weitere
// HTML Data
htmlTablesDE,
htmlSvgDE,
htmlMarqueeDE,
// CSS Grundlagen
// CSS Fundamentals
basicSelectorsDE,
advancedSelectorsEN, // Using EN fallback until translated
colorsEN, // Using EN fallback until translated
typographyEN, // Using EN fallback until translated
boxModelDE,
unitsVariablesDE,
// CSS Graphics
htmlSvgDE,
// CSS Layouts
flexboxDE,
gridEN, // Using EN fallback until translated
responsiveDE,
// CSS Animationen
// CSS Animation
transitionsAnimationsDE,
// Goodbye
goodbyeEN
@@ -164,81 +170,129 @@ const moduleStoreDE = [
// Polish module store - ordered by learning path
const moduleStorePL = [
// Welcome
welcomePL,
// HTML Fundamentals
htmlElementsPL,
htmlFormsBasicPL,
htmlFormsValidationPL,
// HTML Interactive
htmlDetailsSummaryPL,
htmlProgressMeterPL,
// HTML Data
htmlTablesPL,
htmlSvgPL,
htmlMarqueePL,
// CSS Fundamentals
basicSelectorsPL,
advancedSelectorsEN, // Using EN fallback until translated
colorsEN, // Using EN fallback until translated
typographyEN, // Using EN fallback until translated
boxModelPL,
unitsVariablesPL,
// CSS Graphics
htmlSvgPL,
// CSS Layouts
flexboxPL,
gridEN, // Using EN fallback until translated
responsivePL,
// CSS Animation
transitionsAnimationsPL,
// Goodbye
goodbyeEN
];
// Spanish module store - ordered by learning path
const moduleStoreES = [
// Welcome
welcomeES,
// HTML Fundamentals
htmlElementsES,
htmlFormsBasicES,
htmlFormsValidationES,
// HTML Interactive
htmlDetailsSummaryES,
htmlProgressMeterES,
// HTML Data
htmlTablesES,
htmlSvgES,
htmlMarqueeES,
// CSS Fundamentals
basicSelectorsES,
advancedSelectorsEN, // Using EN fallback until translated
colorsEN, // Using EN fallback until translated
typographyEN, // Using EN fallback until translated
boxModelES,
unitsVariablesES,
// CSS Graphics
htmlSvgES,
// CSS Layouts
flexboxES,
gridEN, // Using EN fallback until translated
responsiveES,
// CSS Animation
transitionsAnimationsES,
// Goodbye
goodbyeEN
];
// Arabic module store - ordered by learning path
const moduleStoreAR = [
// Welcome
welcomeAR,
// HTML Fundamentals
htmlElementsAR,
htmlFormsBasicAR,
htmlFormsValidationAR,
// HTML Interactive
htmlDetailsSummaryAR,
htmlProgressMeterAR,
// HTML Data
htmlTablesAR,
htmlSvgAR,
htmlMarqueeAR,
// CSS Fundamentals
basicSelectorsAR,
advancedSelectorsEN, // Using EN fallback until translated
colorsEN, // Using EN fallback until translated
typographyEN, // Using EN fallback until translated
boxModelAR,
unitsVariablesAR,
// CSS Graphics
htmlSvgAR,
// CSS Layouts
flexboxAR,
gridEN, // Using EN fallback until translated
responsiveAR,
// CSS Animation
transitionsAnimationsAR,
// Goodbye
goodbyeEN
];
// Ukrainian module store - ordered by learning path
const moduleStoreUK = [
// Welcome
welcomeUK,
// HTML Fundamentals
htmlElementsUK,
htmlFormsBasicUK,
htmlFormsValidationUK,
// HTML Interactive
htmlDetailsSummaryUK,
htmlProgressMeterUK,
// HTML Data
htmlTablesUK,
htmlSvgUK,
htmlMarqueeUK,
// CSS Fundamentals
basicSelectorsUK,
advancedSelectorsEN, // Using EN fallback until translated
colorsEN, // Using EN fallback until translated
typographyEN, // Using EN fallback until translated
boxModelUK,
unitsVariablesUK,
// CSS Graphics
htmlSvgUK,
// CSS Layouts
flexboxUK,
gridEN, // Using EN fallback until translated
responsiveUK,
// CSS Animation
transitionsAnimationsUK,
// Goodbye
goodbyeEN
];

View File

@@ -20,7 +20,7 @@
</button>
<a href="#" id="logo-link" class="logo">
<img src="./bowl.png" width="40" alt="CODE CRISPIES Logo" />
<h1><span class="code-text">CODE</span><span>CRISPIES</span></h1>
<h1><span class="code-text">CODE</span><span class="crispies-text">CRISPIES</span></h1>
</a>
<div class="header-actions">
<button id="help-btn" class="help-toggle" data-i18n-aria-label="help" aria-label="Help">?</button>

View File

@@ -186,6 +186,10 @@ kbd {
}
.logo h1 .code-text {
color: var(--primary-color);
}
.logo h1 .crispies-text {
background: var(--primary-color);
color: white;
padding: 0.15rem 0.35rem;
@@ -194,10 +198,6 @@ kbd {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
}
.logo h1 span:last-child {
color: var(--primary-color);
}
.help-toggle {
width: 28px;
height: 28px;

View File

@@ -27,7 +27,7 @@ describe("Lessons Config Module", () => {
modules.forEach((module) => {
module.lessons.forEach((lesson) => {
expect(lesson.mode).toBeDefined();
expect(["html", "css", "tailwind"]).toContain(lesson.mode);
expect(["html", "css", "tailwind", "playground"]).toContain(lesson.mode);
});
});
});