diff --git a/lessons/00-basic-selectors.json b/lessons/00-basic-selectors.json
index 1b843e0..915798c 100644
--- a/lessons/00-basic-selectors.json
+++ b/lessons/00-basic-selectors.json
@@ -186,7 +186,7 @@
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
- "solution": ".card.featured { border-color: gold; background-color: lemonchiffon }",
+ "solution": ".card.featured { border-color: gold; background-color: lemonchiffon; }",
"validations": [
{
"type": "regex",
@@ -394,7 +394,7 @@
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
- "solution": "p.note,\nli.important,\n#summary {\n background-color: lightyellow;\n border-left: 3px solid gold;\n padding-left: 10px\n}",
+ "solution": "p.note,\nli.important,\n#summary {\n background-color: lightyellow;\n border-left: 3px solid gold;\n padding-left: 10px;\n}",
"validations": [
{
"type": "contains",
@@ -542,7 +542,7 @@
{
"type": "contains",
"value": "green",
- "message": ""
+ "message": "Set the color to green "
}
]
}
diff --git a/lessons/05-units-variables.json b/lessons/05-units-variables.json
index caf64a5..2ffb2da 100644
--- a/lessons/05-units-variables.json
+++ b/lessons/05-units-variables.json
@@ -8,15 +8,15 @@
{
"id": "units-1",
"title": "Absolute vs. Relative Units",
- "description": "Learn the difference between px, rem, em, %, and vw/vh for flexible, responsive layouts.",
- "task": "Set the width of .box to 80% and max-width to 37.5rem .",
+ "description": "Learn the difference between px, rem, em, %, and vw/vh for flexible, responsive layouts.
width: 80%; /* relative to parent */\nmax-width: 40rem; /* relative to root font */\npadding: 16px; /* fixed pixels */ ",
+ "task": "Set the width of .box to 80% and max-width to 40rem .",
"previewHTML": "Resize me!
",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .box { background: #f5f5f5; padding: 1rem; }",
"sandboxCSS": "",
"codePrefix": "/* Set flexible sizing */\n.box {",
"initialCode": "",
"codeSuffix": "}",
- "solution": " width: 80%;\n max-width: 37.5rem;",
+ "solution": " width: 80%;\n max-width: 40rem;",
"previewContainer": "preview-area",
"validations": [
{ "type": "contains", "value": "width", "message": "Use width property", "options": { "caseSensitive": false } },
@@ -24,23 +24,23 @@
{ "type": "contains", "value": "max-width", "message": "Use max-width property", "options": { "caseSensitive": false } },
{
"type": "property_value",
- "value": { "property": "max-width", "expected": "37.5rem" },
- "message": "Set max-width to 37.5rem "
+ "value": { "property": "max-width", "expected": "40rem" },
+ "message": "Set max-width to 40rem "
}
]
},
{
"id": "units-2",
"title": "CSS Custom Properties",
- "description": "Define and reuse variables (--custom properties) to centralize your theme values.:root {\n --main-color: #6200ee;\n}\n.element {\n color: var(--main-color);\n} ",
- "task": "Create a --main-color variable in :root with #6200ee and apply it as the border color on .themed .",
+ "description": "Define and reuse variables (--custom properties) to centralize your theme values.:root {\n --main-color: mediumpurple;\n}\n.themed {\n border-color: var(--main-color);\n} ",
+ "task": "Create a --main-color variable in :root with mediumpurple and apply it as the border color on .themed .",
"previewHTML": "Variable Box
",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .themed { padding: 1rem; border: 0.125rem solid #ddd; }",
"sandboxCSS": "",
"codePrefix": "/* Define and use a CSS variable */\n:root {",
"initialCode": "",
"codeSuffix": "}\n.themed { }",
- "solution": " --main-color: #6200ee;\n}\n.themed {\n border-color: var(--main-color);",
+ "solution": " --main-color: mediumpurple;\n}\n.themed {\n border-color: var(--main-color);",
"previewContainer": "preview-area",
"validations": [
{
@@ -66,7 +66,7 @@
{
"id": "units-3",
"title": "Unit Calculations (calc)",
- "description": "Use the calc() function to combine different units in one expression..element {\n width: calc(100% - 2rem);\n height: calc(50vh + 1rem);\n} ",
+ "description": "Use the calc() function to combine different units in one expression.width: calc(100% - 2rem);\nmin-height: calc(10vh + 1rem); ",
"task": "Set the width of .sized to calc(100% - 2rem) and min-height to calc(10vh + 1rem) .",
"previewHTML": "Calc Demo
",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .sized { background: #e8f5e9; padding: 1rem; }",
@@ -95,7 +95,7 @@
{
"id": "units-4",
"title": "Viewport & Responsive Units",
- "description": "Control layouts relative to viewport size with vw, vh, and vmin/vmax units.",
+ "description": "Control layouts relative to viewport size with vw, vh, and vmin/vmax units.width: 50vw; /* 50% of viewport width */\nheight: 20vh; /* 20% of viewport height */ ",
"task": "Give .view a width of 50vw and height of 20vh .",
"previewHTML": "Viewport Box
",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .view { background: #ffe0b2; }",
diff --git a/lessons/08-responsive.json b/lessons/08-responsive.json
index 43de4e5..cd1be02 100644
--- a/lessons/08-responsive.json
+++ b/lessons/08-responsive.json
@@ -8,7 +8,7 @@
{
"id": "responsive-1",
"title": "Media Queries",
- "description": "Understand the syntax and use cases for CSS media queries to apply styles conditionally based on viewport characteristics.@media (max-width: 600px) {\n .element {\n background: lightcoral;\n }\n} ",
+ "description": "Understand the syntax and use cases for CSS media queries to apply styles conditionally based on viewport characteristics.@media (max-width: 600px) {\n .panel {\n background: lightcoral;\n }\n} ",
"task": "Write a media query with @media (max-width: 600px) that changes .panel background to lightcoral .",
"previewHTML": "Resize the window
",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .panel { padding: 1rem; background: lightblue; }",
@@ -58,7 +58,7 @@
},
{
"id": "responsive-3",
- "title": "Flex Grids",
+ "title": "Responsive Grid",
"description": "Combine CSS Grid with auto-fit or auto-fill for responsive column layouts.",
"task": "Add display: grid , grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) , and gap: 1rem to .cards .",
"previewHTML": "",
diff --git a/lessons/24-html-progress-meter.json b/lessons/24-html-progress-meter.json
index 1bf278f..d8c2917 100644
--- a/lessons/24-html-progress-meter.json
+++ b/lessons/24-html-progress-meter.json
@@ -86,11 +86,31 @@
"value": { "selector": "meter", "attr": "value", "value": "0.8" },
"message": "Set value= \"0.8\" on the meter"
},
+ {
+ "type": "attribute_value",
+ "value": { "selector": "meter", "attr": "min", "value": "0" },
+ "message": "Set min= \"0\" on the meter"
+ },
+ {
+ "type": "attribute_value",
+ "value": { "selector": "meter", "attr": "max", "value": "1" },
+ "message": "Set max= \"1\" on the meter"
+ },
{
"type": "attribute_value",
"value": { "selector": "meter", "attr": "low", "value": "0.2" },
"message": "Set low= \"0.2\" to define the low threshold"
},
+ {
+ "type": "attribute_value",
+ "value": { "selector": "meter", "attr": "high", "value": "0.8" },
+ "message": "Set high= \"0.8\" to define the high threshold"
+ },
+ {
+ "type": "attribute_value",
+ "value": { "selector": "meter", "attr": "optimum", "value": "1" },
+ "message": "Set optimum= \"1\" to indicate the optimal value"
+ },
{
"type": "element_exists",
"value": "label",
diff --git a/lessons/32-html-svg.json b/lessons/32-html-svg.json
index 2a96917..37bd7a6 100644
--- a/lessons/32-html-svg.json
+++ b/lessons/32-html-svg.json
@@ -15,7 +15,7 @@
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: #f5f5f5; display: flex; justify-content: center; } svg { background: white; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }",
"sandboxCSS": "",
"initialCode": "",
- "solution": "\n \n ",
+ "solution": "\n \n ",
"previewContainer": "preview-area",
"validations": [
{
@@ -28,6 +28,16 @@
"value": "circle",
"message": "Add a <circle> element inside the SVG"
},
+ {
+ "type": "attribute_value",
+ "value": { "selector": "svg", "attr": "width", "value": "200" },
+ "message": "Set width= \"200\" on the SVG"
+ },
+ {
+ "type": "attribute_value",
+ "value": { "selector": "svg", "attr": "height", "value": "200" },
+ "message": "Set height= \"200\" on the SVG"
+ },
{
"type": "attribute_value",
"value": { "selector": "circle", "attr": "cx", "value": "100" },
@@ -37,6 +47,11 @@
"type": "attribute_value",
"value": { "selector": "circle", "attr": "cy", "value": "100" },
"message": "Set cy= \"100\" for the circle's vertical center"
+ },
+ {
+ "type": "attribute_value",
+ "value": { "selector": "circle", "attr": "r", "value": "50" },
+ "message": "Set r= \"50\" for the circle's radius"
}
]
},
@@ -49,7 +64,7 @@
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 200px; display: flex; justify-content: center; align-items: center; } svg { background: white; border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); }",
"sandboxCSS": "",
"initialCode": "",
- "solution": "\n \n \n ",
+ "solution": "\n \n \n ",
"previewContainer": "preview-area",
"validations": [
{
@@ -66,6 +81,61 @@
"type": "element_exists",
"value": "line",
"message": "Add a <line> element"
+ },
+ {
+ "type": "attribute_value",
+ "value": { "selector": "svg", "attr": "width", "value": "200" },
+ "message": "Set width= \"200\" on the SVG"
+ },
+ {
+ "type": "attribute_value",
+ "value": { "selector": "svg", "attr": "height", "value": "150" },
+ "message": "Set height= \"150\" on the SVG"
+ },
+ {
+ "type": "attribute_value",
+ "value": { "selector": "rect", "attr": "x", "value": "20" },
+ "message": "Set x= \"20\" on the rect"
+ },
+ {
+ "type": "attribute_value",
+ "value": { "selector": "rect", "attr": "y", "value": "20" },
+ "message": "Set y= \"20\" on the rect"
+ },
+ {
+ "type": "attribute_value",
+ "value": { "selector": "rect", "attr": "width", "value": "80" },
+ "message": "Set width= \"80\" on the rect"
+ },
+ {
+ "type": "attribute_value",
+ "value": { "selector": "rect", "attr": "height", "value": "60" },
+ "message": "Set height= \"60\" on the rect"
+ },
+ {
+ "type": "attribute_value",
+ "value": { "selector": "line", "attr": "x1", "value": "120" },
+ "message": "Set x1= \"120\" on the line"
+ },
+ {
+ "type": "attribute_value",
+ "value": { "selector": "line", "attr": "y1", "value": "30" },
+ "message": "Set y1= \"30\" on the line"
+ },
+ {
+ "type": "attribute_value",
+ "value": { "selector": "line", "attr": "x2", "value": "180" },
+ "message": "Set x2= \"180\" on the line"
+ },
+ {
+ "type": "attribute_value",
+ "value": { "selector": "line", "attr": "y2", "value": "90" },
+ "message": "Set y2= \"90\" on the line"
+ },
+ {
+ "type": "contains",
+ "value": "stroke",
+ "message": "Add a stroke color to the line"
}
]
},
@@ -78,7 +148,7 @@
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%); min-height: 250px; display: flex; justify-content: center; align-items: center; } svg { background: white; border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.15); }",
"sandboxCSS": "",
"initialCode": "",
- "solution": "\n \n \n \n \n ",
+ "solution": "\n \n \n \n \n ",
"previewContainer": "preview-area",
"validations": [
{