diff --git a/lessons/00-basic-selectors.json b/lessons/00-basic-selectors.json
index 84331cd..03ae9c1 100644
--- a/lessons/00-basic-selectors.json
+++ b/lessons/00-basic-selectors.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
- "message": "Add color: coral;"
+ "message": "Which property controls text color?"
}
]
},
@@ -43,12 +43,12 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "lavender" },
- "message": "Add background: lavender;"
+ "message": "Check the background property"
},
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Add padding: 1rem;"
+ "message": "The card needs space inside its edges"
}
]
},
@@ -74,7 +74,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "steelblue" },
- "message": "Set color: steelblue"
+ "message": "Which property changes text color?"
}
]
},
@@ -100,7 +100,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
- "message": "Set color: coral"
+ "message": "What value gives a warm, reddish-orange color?"
}
]
},
@@ -126,7 +126,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "tomato" },
- "message": "Set background: tomato"
+ "message": "The badge needs a bright red background"
}
]
},
@@ -152,7 +152,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "steelblue" },
- "message": "Set background: steelblue"
+ "message": "Which property sets the button's fill color?"
}
]
},
@@ -178,7 +178,7 @@
{
"type": "property_value",
"value": { "property": "text-decoration", "expected": "none" },
- "message": "Set text-decoration: none"
+ "message": "Which property controls the underline on links?"
}
]
},
@@ -199,7 +199,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "steelblue" },
- "message": "Set color: steelblue"
+ "message": "Check the color property"
}
]
},
@@ -225,7 +225,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "white" },
- "message": "Set color: white"
+ "message": "The links need to stand out against the blue background"
}
]
},
@@ -251,7 +251,7 @@
{
"type": "property_value",
"value": { "property": "font-size", "expected": "0.9rem" },
- "message": "Set font-size: 0.9rem"
+ "message": "Check the font-size property — the text should be slightly smaller"
}
]
}
diff --git a/lessons/00-basics.json b/lessons/00-basics.json
index 3969734..084ac96 100644
--- a/lessons/00-basics.json
+++ b/lessons/00-basics.json
@@ -147,7 +147,7 @@
"property": "padding",
"expected": "20px"
},
- "message": "Set the padding value to 20px",
+ "message": "How much breathing room does the content need? Re-read the task for the exact size",
"options": {
"exact": true
}
@@ -181,7 +181,7 @@
"property": "margin-bottom",
"expected": "30px"
},
- "message": "Set the margin-bottom value to 30px",
+ "message": "How much space should separate the title from the content below? Check the task for the amount",
"options": {
"exact": true
}
@@ -212,7 +212,7 @@
{
"type": "regex",
"value": "border:\\s*2px\\s+solid\\s+blue",
- "message": "Set the border to 2px solid blue",
+ "message": "The border shorthand takes three parts: width, style, and color",
"options": {
"caseSensitive": false
}
@@ -246,7 +246,7 @@
"property": "justify-content",
"expected": "center"
},
- "message": "Set justify-content to center",
+ "message": "How do you center items along the main axis?",
"options": {
"exact": true
}
@@ -265,7 +265,7 @@
"property": "align-items",
"expected": "center"
},
- "message": "Set align-items to center",
+ "message": "Which property centers items along the cross axis?",
"options": {
"exact": true
}
@@ -327,7 +327,7 @@
{
"type": "regex",
"value": "font-family:\\s*Courier,\\s*monospace",
- "message": "Set the font-family to Courier, monospace",
+ "message": "A font stack lists preferred fonts first, followed by a generic fallback, separated by commas",
"options": {
"caseSensitive": false
}
diff --git a/lessons/01-advanced-selectors.json b/lessons/01-advanced-selectors.json
index 1e9ee3a..859e904 100644
--- a/lessons/01-advanced-selectors.json
+++ b/lessons/01-advanced-selectors.json
@@ -22,7 +22,7 @@
{
"type": "regex",
"value": "^input\\[type=\"text\"\\]\\s*{",
- "message": "Use input[type=\"text\"] { … } as your attribute selector",
+ "message": "Which attribute selector syntax targets inputs with a specific type? Check the square-bracket notation from the description.",
"options": {
"caseSensitive": true
}
@@ -85,7 +85,7 @@
{
"type": "regex",
"value": "^a\\[href\\^=\"https\"\\]\\s*{",
- "message": "Use a[href^=\"https\"] { … } as your attribute selector to target HTTPS links",
+ "message": "Which partial-match attribute selector targets values that start with a given string? Combine the element name with that selector.",
"options": {
"caseSensitive": true
}
@@ -145,7 +145,7 @@
{
"type": "regex",
"value": "^\\.main-nav\\s*>\\s*li\\s*{",
- "message": "Use .main-nav > li { … } with the child combinator to target only direct children",
+ "message": "Which combinator selects only direct children, skipping deeper descendants? Place it between the parent and child selectors.",
"options": {
"caseSensitive": true
}
@@ -203,7 +203,7 @@
{
"type": "regex",
"value": "^nav\\s+a\\s*{",
- "message": "Use nav a with a space between nav and a",
+ "message": "The descendant combinator is the simplest one — what character separates a parent selector from a descendant selector?",
"options": {
"caseSensitive": true
}
@@ -261,7 +261,7 @@
{
"type": "regex",
"value": "^h2\\s*\\+\\s*p\\s*{",
- "message": "Use h2 + p with the adjacent sibling combinator (+)",
+ "message": "Which combinator targets the element immediately following a sibling? Place it between the two element selectors.",
"options": {
"caseSensitive": true
}
@@ -319,7 +319,7 @@
{
"type": "regex",
"value": "^h3\\s*~\\s*p\\s*{",
- "message": "Use h3 ~ p with the general sibling combinator (~)",
+ "message": "Which combinator selects all later siblings, not just the one right next to it? Place it between the two element selectors.",
"options": {
"caseSensitive": true
}
@@ -377,7 +377,7 @@
{
"type": "regex",
"value": "^button:hover\\s*{",
- "message": "Use button:hover to target buttons on hover",
+ "message": "Which pseudo-class activates when the cursor is over an element? Attach it to the button selector with a colon.",
"options": {
"caseSensitive": true
}
@@ -435,7 +435,7 @@
{
"type": "regex",
"value": "^li:first-child\\s*{",
- "message": "Use li:first-child to target first list items",
+ "message": "Which pseudo-class selects an element only when it is the first child of its parent? Attach it to the li selector.",
"options": {
"caseSensitive": true
}
diff --git a/lessons/01-box-model.json b/lessons/01-box-model.json
index ed32a0d..636721d 100644
--- a/lessons/01-box-model.json
+++ b/lessons/01-box-model.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Set padding: 1rem"
+ "message": "Which property adds space between an element's content and its border?"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+steelblue",
- "message": "Set border-left: 4px solid steelblue",
+ "message": "Use the border-left shorthand with width, style, and color values",
"options": { "caseSensitive": false }
}
]
@@ -65,7 +65,7 @@
{
"type": "property_value",
"value": { "property": "margin-bottom", "expected": "1rem" },
- "message": "Set margin-bottom: 1rem"
+ "message": "Which property creates space below an element, pushing neighbors away?"
}
]
},
@@ -86,7 +86,7 @@
{
"type": "property_value",
"value": { "property": "box-sizing", "expected": "border-box" },
- "message": "Set box-sizing: border-box"
+ "message": "Which box-sizing value includes padding and border in the element's total width?"
}
]
},
@@ -107,7 +107,7 @@
{
"type": "regex",
"value": "padding:\\s*8px\\s+1rem",
- "message": "Set padding: 8px 1rem",
+ "message": "Use the padding shorthand with two values: vertical then horizontal",
"options": { "caseSensitive": false }
}
]
@@ -129,7 +129,7 @@
{
"type": "regex",
"value": "margin:\\s*0\\s+auto",
- "message": "Set margin: 0 auto",
+ "message": "Use margin with a keyword that auto-calculates equal left and right spacing",
"options": { "caseSensitive": false }
}
]
@@ -151,7 +151,7 @@
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "50%" },
- "message": "Set border-radius: 50%"
+ "message": "Which border-radius percentage creates a perfect circle from a square element?"
}
]
},
@@ -172,18 +172,18 @@
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Set padding: 1rem"
+ "message": "Add inner spacing to the notification card"
},
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+coral",
- "message": "Set border-left: 4px solid coral",
+ "message": "Add a left border accent using the border-left shorthand",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "4px" },
- "message": "Set border-radius: 4px"
+ "message": "Round the corners slightly with border-radius"
}
]
}
diff --git a/lessons/03-colors.json b/lessons/03-colors.json
index 11f0884..033065d 100644
--- a/lessons/03-colors.json
+++ b/lessons/03-colors.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "background-color", "expected": "seashell" },
- "message": "Set background-color: seashell"
+ "message": "Which property sets the fill color behind an element's content area?"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
- "message": "Set color: coral"
+ "message": "Which CSS property changes the color of text content?"
}
]
},
@@ -64,7 +64,7 @@
{
"type": "property_value",
"value": { "property": "border-color", "expected": "coral" },
- "message": "Set border-color: coral"
+ "message": "Which property changes just the color of an existing border?"
}
]
},
@@ -85,7 +85,7 @@
{
"type": "property_value",
"value": { "property": "background-color", "expected": "#ffd700" },
- "message": "Set background-color: #ffd700"
+ "message": "Set the background-color using a hex code format"
}
]
}
diff --git a/lessons/04-typography.json b/lessons/04-typography.json
index 9dda4b8..427ce20 100644
--- a/lessons/04-typography.json
+++ b/lessons/04-typography.json
@@ -142,7 +142,7 @@
{
"type": "contains",
"value": "2px 2px",
- "message": "Set offset to 2px 2px"
+ "message": "How far should the shadow move horizontally and vertically?"
}
]
}
diff --git a/lessons/05-units-variables.json b/lessons/05-units-variables.json
index 5a76705..a8b1dce 100644
--- a/lessons/05-units-variables.json
+++ b/lessons/05-units-variables.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "max-width", "expected": "40rem" },
- "message": "Set max-width: 40rem"
+ "message": "Which property caps an element's width? Try a rem value for readable line length."
}
]
},
@@ -71,7 +71,7 @@
{
"type": "regex",
"value": "width:\\s*calc\\(\\s*100%\\s*-\\s*200px\\s*\\)",
- "message": "Set width: calc(100% - 200px)",
+ "message": "Use calc() to subtract the sidebar's fixed width from the full container width.",
"options": { "caseSensitive": false }
}
]
@@ -93,7 +93,7 @@
{
"type": "property_value",
"value": { "property": "min-height", "expected": "100vh" },
- "message": "Set min-height: 100vh"
+ "message": "Which property ensures a minimum height? Use a viewport unit for full-screen coverage."
}
]
}
diff --git a/lessons/06-transitions-animations.json b/lessons/06-transitions-animations.json
index e61cc7d..7f2624b 100644
--- a/lessons/06-transitions-animations.json
+++ b/lessons/06-transitions-animations.json
@@ -28,7 +28,7 @@
{
"type": "regex",
"value": "transition:\\s*background-color\\s*0\\.3s",
- "message": "Set transition: background-color 0.3s",
+ "message": "Specify which property to transition and how long it should take.",
"options": { "caseSensitive": false }
}
]
@@ -56,7 +56,7 @@
{
"type": "property_value",
"value": { "property": "transition-timing-function", "expected": "ease-in-out" },
- "message": "Set timing to ease-in-out"
+ "message": "Which easing keyword starts slow, speeds up, then slows down again?"
}
]
},
@@ -95,7 +95,7 @@
{
"type": "regex",
"value": "animation:.*bounce.*1s.*infinite",
- "message": "Apply animation: bounce 1s infinite",
+ "message": "Use the animation shorthand: name, duration, and repeat count.",
"options": { "caseSensitive": false }
}
]
@@ -117,27 +117,27 @@
{
"type": "property_value",
"value": { "property": "animation-name", "expected": "pulse" },
- "message": "Set animation-name: pulse"
+ "message": "Which property links an element to a named @keyframes rule?"
},
{
"type": "property_value",
"value": { "property": "animation-duration", "expected": "2s" },
- "message": "Set animation-duration: 2s"
+ "message": "How long should one full cycle of the animation take?"
},
{
"type": "property_value",
"value": { "property": "animation-delay", "expected": "1s" },
- "message": "Set animation-delay: 1s"
+ "message": "Which property makes the animation wait before starting?"
},
{
"type": "property_value",
"value": { "property": "animation-iteration-count", "expected": "2" },
- "message": "Set animation-iteration-count: 2"
+ "message": "Which property controls how many times the animation repeats?"
},
{
"type": "property_value",
"value": { "property": "animation-fill-mode", "expected": "forwards" },
- "message": "Set animation-fill-mode: forwards"
+ "message": "Which property keeps the element styled in its final keyframe state after the animation ends?"
}
]
}
diff --git a/lessons/07-layouts.json b/lessons/07-layouts.json
index 6873966..32e69b4 100644
--- a/lessons/07-layouts.json
+++ b/lessons/07-layouts.json
@@ -18,14 +18,24 @@
"codeSuffix": "}",
"previewContainer": "preview-area",
"validations": [
- { "type": "contains", "value": "display", "message": "Use display: flex", "options": { "caseSensitive": false } },
+ {
+ "type": "contains",
+ "value": "display",
+ "message": "Which display mode arranges children in a row or column?",
+ "options": { "caseSensitive": false }
+ },
{
"type": "contains",
"value": "justify-content",
- "message": "Use justify-content: center",
+ "message": "How do you center items along the main axis?",
"options": { "caseSensitive": false }
},
- { "type": "contains", "value": "align-items", "message": "Use align-items: center", "options": { "caseSensitive": false } }
+ {
+ "type": "contains",
+ "value": "align-items",
+ "message": "Which property centers items along the cross axis?",
+ "options": { "caseSensitive": false }
+ }
]
},
{
@@ -44,13 +54,13 @@
{
"type": "contains",
"value": "flex-wrap: wrap",
- "message": "Use flex-wrap: wrap",
+ "message": "Which property allows flex items to flow onto multiple lines?",
"options": { "caseSensitive": false }
},
{
"type": "regex",
"value": ".item.*flex:\\s*1\\s+1\\s+100px",
- "message": "Set flex: 1 1 100px on items",
+ "message": "The flex shorthand takes grow, shrink, and basis values — what basis size should each item start from?",
"options": { "caseSensitive": false }
}
]
@@ -68,17 +78,22 @@
"codeSuffix": "}",
"previewContainer": "preview-area",
"validations": [
- { "type": "contains", "value": "display: grid", "message": "Use display: grid", "options": { "caseSensitive": false } },
+ {
+ "type": "contains",
+ "value": "display: grid",
+ "message": "Which display mode lets you define rows and columns?",
+ "options": { "caseSensitive": false }
+ },
{
"type": "contains",
"value": "grid-template-columns",
- "message": "Define grid-template-columns",
+ "message": "Which property defines the column structure of a grid?",
"options": { "caseSensitive": false }
},
{
"type": "regex",
"value": "grid-template-columns:\\s*repeat\\(3,\\s*1fr\\)\\s*",
- "message": "Create three equal columns with repeat(3, 1fr)",
+ "message": "The repeat() function can create equal-width columns — how many do you need, and what unit makes them equal?",
"options": { "caseSensitive": false }
},
{ "type": "contains", "value": "gap", "message": "Use gap property", "options": { "caseSensitive": false } }
@@ -106,7 +121,7 @@
{
"type": "property_value",
"value": { "property": "grid-column", "expected": "1 / span 2" },
- "message": "Span across 2 columns with grid-column: 1 / span 2",
+ "message": "Use grid-column with a start line and a span count \u2014 how many columns should this item stretch across?",
"options": { "caseSensitive": false }
}
]
diff --git a/lessons/08-responsive.json b/lessons/08-responsive.json
index edc9bf8..34862dc 100644
--- a/lessons/08-responsive.json
+++ b/lessons/08-responsive.json
@@ -22,7 +22,7 @@
{
"type": "regex",
"value": "@media\\s*\\(max-width:\\s*600px\\)",
- "message": "Use @media (max-width: 600px)",
+ "message": "Start with an @media rule \u2014 which condition targets screens 600px wide or smaller?",
"options": { "caseSensitive": false }
},
{
@@ -34,7 +34,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "lightcoral" },
- "message": "Set background: lightcoral",
+ "message": "Which property changes the element's background color?",
"options": { "exact": false }
}
]
@@ -53,7 +53,11 @@
"solution": " font-size: 5vw;",
"previewContainer": "preview-area",
"validations": [
- { "type": "property_value", "value": { "property": "font-size", "expected": "5vw" }, "message": "Set font-size: 5vw" }
+ {
+ "type": "property_value",
+ "value": { "property": "font-size", "expected": "5vw" },
+ "message": "Which CSS unit scales relative to the viewport width?"
+ }
]
},
{
@@ -73,18 +77,18 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "grid" },
- "message": "Set display: grid"
+ "message": "Which display mode lets you define rows and columns?"
},
{
"type": "regex",
"value": "repeat\\(auto-fit,\\s*minmax\\(200px,\\s*1fr\\)\\)",
- "message": "Use repeat(auto-fit, minmax(200px, 1fr))",
+ "message": "Try repeat() with auto-fit and minmax() — what minimum and maximum sizes create flexible columns?",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
- "message": "Set gap: 1rem"
+ "message": "Which property adds space between grid items?"
}
]
},
@@ -105,7 +109,7 @@
{
"type": "regex",
"value": "@media\\s*\\(min-width:\\s*768px\\)",
- "message": "Use @media (min-width: 768px)",
+ "message": "Which @media condition applies styles when the viewport is at least 768px wide?",
"options": { "caseSensitive": false }
},
{
@@ -117,7 +121,7 @@
{
"type": "property_value",
"value": { "property": "width", "expected": "250px" },
- "message": "Set width: 250px",
+ "message": "Which property controls how wide the sidebar should be on larger screens?",
"options": { "exact": false }
}
]
diff --git a/lessons/09-gradients.json b/lessons/09-gradients.json
index 808c01a..a62fb19 100644
--- a/lessons/09-gradients.json
+++ b/lessons/09-gradients.json
@@ -22,7 +22,7 @@
{
"type": "contains",
"value": "linear-gradient",
- "message": "Use linear-gradient()"
+ "message": "Which CSS function creates a smooth transition between colors along a straight line?"
},
{
"type": "contains",
@@ -53,7 +53,7 @@
{
"type": "contains",
"value": "to right",
- "message": "Add to right to set the direction"
+ "message": "Which direction keyword makes a gradient flow horizontally from the left side?"
}
]
},
@@ -74,7 +74,7 @@
{
"type": "contains",
"value": "radial-gradient",
- "message": "Use radial-gradient()"
+ "message": "Which CSS function creates a gradient that radiates outward from a center point?"
},
{
"type": "contains",
diff --git a/lessons/10-tailwind-basics.json b/lessons/10-tailwind-basics.json
index c7f5f85..cfe612f 100644
--- a/lessons/10-tailwind-basics.json
+++ b/lessons/10-tailwind-basics.json
@@ -20,7 +20,7 @@
{
"type": "contains_class",
"value": "bg-blue-500",
- "message": "Add the bg-blue-500 class for a blue background."
+ "message": "Which Tailwind utility sets a blue background color? Think about the bg-{color}-{shade} pattern."
}
]
},
@@ -38,22 +38,22 @@
{
"type": "contains_class",
"value": "bg-white",
- "message": "Add bg-white to set the background color to white."
+ "message": "Which Tailwind utility sets a white background? The pattern is bg-{color}."
},
{
"type": "contains_class",
"value": "p-4",
- "message": "Add p-4 to apply 1rem padding on all sides."
+ "message": "Which Tailwind utility adds 1rem padding on all sides? Remember: each spacing unit is 0.25rem."
},
{
"type": "contains_class",
"value": "rounded",
- "message": "Add rounded to apply border-radius of 0.25rem."
+ "message": "Which Tailwind utility adds rounded corners? It is one of the simplest utility names."
},
{
"type": "contains_class",
"value": "shadow-sm",
- "message": "Add shadow-sm to apply small drop-shadow."
+ "message": "Which Tailwind utility adds a small drop-shadow? Look for a shadow- variant."
}
]
},
@@ -71,17 +71,17 @@
{
"type": "contains_class",
"value": "text-blue-600",
- "message": "Add text-blue-600 to make the text blue"
+ "message": "Which Tailwind utility controls text color? Use the text-{color}-{shade} pattern with a blue shade."
},
{
"type": "contains_class",
"value": "text-2xl",
- "message": "Add text-2xl to increase the font size to 1.5rem"
+ "message": "Which Tailwind utility sets the font size to 1.5rem? Check the text-{size} scale."
},
{
"type": "contains_class",
"value": "font-bold",
- "message": "Add font-bold to make the text bold (font-weight: 700)"
+ "message": "Which Tailwind utility makes text bold? The font-{weight} pattern controls font weight."
}
]
},
@@ -99,17 +99,17 @@
{
"type": "contains_class",
"value": "px-6",
- "message": "Add px-6 for horizontal padding (1.5rem left and right)"
+ "message": "Which Tailwind utility adds horizontal padding of 1.5rem? The px- prefix targets left and right."
},
{
"type": "contains_class",
"value": "py-3",
- "message": "Add py-3 for vertical padding (0.75rem top and bottom)"
+ "message": "Which Tailwind utility adds vertical padding of 0.75rem? The py- prefix targets top and bottom."
},
{
"type": "contains_class",
"value": "mx-auto",
- "message": "Add mx-auto to center the button horizontally"
+ "message": "Which Tailwind utility centers an element horizontally using auto margins?"
}
]
},
@@ -127,32 +127,32 @@
{
"type": "contains_class",
"value": "w-full",
- "message": "Add w-full for 100% width on mobile"
+ "message": "Which Tailwind utility makes an element take up 100% width? This is the base (mobile) style."
},
{
"type": "contains_class",
"value": "md:w-1/2",
- "message": "Add md:w-1/2 for 50% width on tablet and up"
+ "message": "How do you set 50% width at the md: breakpoint? Tailwind uses fraction notation for widths."
},
{
"type": "contains_class",
"value": "lg:w-1/3",
- "message": "Add lg:w-1/3 for 33.33% width on desktop and up"
+ "message": "How do you set one-third width at the lg: breakpoint? Use the same fraction pattern."
},
{
"type": "contains_class",
"value": "text-lg",
- "message": "Add text-lg for the base text size"
+ "message": "Which Tailwind text size utility is one step above the base size? Think about the text-{size} scale."
},
{
"type": "contains_class",
"value": "md:text-xl",
- "message": "Add md:text-xl for larger text on tablets"
+ "message": "How do you increase the text size at the md: breakpoint? Go one step larger."
},
{
"type": "contains_class",
"value": "lg:text-2xl",
- "message": "Add lg:text-2xl for even larger text on desktop"
+ "message": "How do you set an even larger text size at the lg: breakpoint? Continue stepping up the scale."
}
]
}
diff --git a/lessons/11-filters.json b/lessons/11-filters.json
index 11fdd7b..8987ee6 100644
--- a/lessons/11-filters.json
+++ b/lessons/11-filters.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "filter", "expected": "blur(4px)" },
- "message": "Set filter: blur(4px)"
+ "message": "Which CSS property applies visual effects like blur? Use the blur() function with a pixel value."
}
]
},
@@ -48,7 +48,7 @@
{
"type": "contains",
"value": "100%",
- "message": "Set to 100% for full grayscale"
+ "message": "What percentage value removes all color completely?"
}
]
},
@@ -74,7 +74,7 @@
{
"type": "contains",
"value": "120%",
- "message": "Set to 120%"
+ "message": "What percentage makes the element slightly brighter than normal? Normal is 100%."
}
]
},
@@ -100,7 +100,7 @@
{
"type": "contains",
"value": "4px 4px 8px",
- "message": "Set shadow offset and blur"
+ "message": "Set the x-offset, y-offset, and blur radius. The task describes the exact values needed."
}
]
}
diff --git a/lessons/12-positioning.json b/lessons/12-positioning.json
index dcfb0af..daf99ea 100644
--- a/lessons/12-positioning.json
+++ b/lessons/12-positioning.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "position", "expected": "relative" },
- "message": "Set position: relative"
+ "message": "Which position value keeps an element in normal flow but allows offset adjustments?"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "property_value",
"value": { "property": "top", "expected": "-8px" },
- "message": "Set top: -8px"
+ "message": "Which offset property moves an element upward from its current position?"
}
]
},
@@ -64,7 +64,7 @@
{
"type": "property_value",
"value": { "property": "position", "expected": "absolute" },
- "message": "Set position: absolute"
+ "message": "Which position value removes an element from normal flow for precise placement?"
}
]
},
@@ -85,12 +85,12 @@
{
"type": "property_value",
"value": { "property": "top", "expected": "8px" },
- "message": "Set top: 8px"
+ "message": "Which offset property controls the distance from the top of the positioned ancestor?"
},
{
"type": "property_value",
"value": { "property": "right", "expected": "8px" },
- "message": "Set right: 8px"
+ "message": "Which offset property controls the distance from the right edge?"
}
]
}
diff --git a/lessons/13-pseudo-elements.json b/lessons/13-pseudo-elements.json
index 02da42d..bb701b6 100644
--- a/lessons/13-pseudo-elements.json
+++ b/lessons/13-pseudo-elements.json
@@ -48,7 +48,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
- "message": "Set color: coral"
+ "message": "Which CSS property changes the text color of the bullet? Try a warm, pinkish-orange named color."
}
]
},
@@ -95,17 +95,17 @@
{
"type": "property_value",
"value": { "property": "width", "expected": "40px" },
- "message": "Set width: 40px"
+ "message": "How wide should the decorative line be? Check the task for the pixel value."
},
{
"type": "property_value",
"value": { "property": "height", "expected": "3px" },
- "message": "Set height: 3px"
+ "message": "Which CSS property controls the thickness of the line? A thin line looks best here."
},
{
"type": "property_value",
"value": { "property": "background", "expected": "steelblue" },
- "message": "Set background: steelblue"
+ "message": "Which CSS property fills the line with color? Use a steel-toned blue named color."
}
]
}
diff --git a/lessons/ar/00-basic-selectors.json b/lessons/ar/00-basic-selectors.json
index 97f4f04..1b8424c 100644
--- a/lessons/ar/00-basic-selectors.json
+++ b/lessons/ar/00-basic-selectors.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
- "message": "أضف color: coral;"
+ "message": "ما الخاصية التي تتحكم في لون النص؟"
}
]
},
@@ -43,12 +43,12 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "lavender" },
- "message": "أضف background: lavender;"
+ "message": "تحقق من خاصية background"
},
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "أضف padding: 1rem;"
+ "message": "البطاقة تحتاج إلى مساحة داخل حوافها"
}
]
},
@@ -74,7 +74,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "steelblue" },
- "message": "اضبط color: steelblue"
+ "message": "ما الخاصية التي تغيّر لون النص؟"
}
]
},
@@ -100,7 +100,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
- "message": "اضبط color: coral"
+ "message": "ما القيمة التي تعطي لوناً دافئاً برتقالياً محمراً؟"
}
]
},
@@ -126,7 +126,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "tomato" },
- "message": "اضبط background: tomato"
+ "message": "الشارة تحتاج إلى خلفية حمراء زاهية"
}
]
},
@@ -152,7 +152,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "steelblue" },
- "message": "اضبط background: steelblue"
+ "message": "ما الخاصية التي تضبط لون تعبئة الزر؟"
}
]
},
@@ -178,7 +178,7 @@
{
"type": "property_value",
"value": { "property": "text-decoration", "expected": "none" },
- "message": "اضبط text-decoration: none"
+ "message": "ما الخاصية التي تتحكم في الخط أسفل الروابط؟"
}
]
},
@@ -199,7 +199,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "steelblue" },
- "message": "اضبط color: steelblue"
+ "message": "تحقق من خاصية color"
}
]
},
@@ -225,7 +225,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "white" },
- "message": "اضبط color: white"
+ "message": "الروابط تحتاج إلى أن تبرز على الخلفية الزرقاء"
}
]
},
@@ -251,7 +251,7 @@
{
"type": "property_value",
"value": { "property": "font-size", "expected": "0.9rem" },
- "message": "اضبط font-size: 0.9rem"
+ "message": "تحقق من خاصية font-size — النص يجب أن يكون أصغر قليلاً"
}
]
}
diff --git a/lessons/ar/01-box-model.json b/lessons/ar/01-box-model.json
index 0b9ca38..d65c4a1 100644
--- a/lessons/ar/01-box-model.json
+++ b/lessons/ar/01-box-model.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "اضبط padding: 1rem"
+ "message": "ما الخاصية التي تضيف مساحة بين محتوى العنصر وحدوده؟"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+steelblue",
- "message": "اضبط border-left: 4px solid steelblue",
+ "message": "استخدم اختصار border-left مع قيم العرض والنمط واللون",
"options": { "caseSensitive": false }
}
]
@@ -65,7 +65,7 @@
{
"type": "property_value",
"value": { "property": "margin-bottom", "expected": "1rem" },
- "message": "اضبط margin-bottom: 1rem"
+ "message": "ما الخاصية التي تُنشئ مساحة أسفل العنصر وتدفع الجيران بعيداً؟"
}
]
},
@@ -86,7 +86,7 @@
{
"type": "property_value",
"value": { "property": "box-sizing", "expected": "border-box" },
- "message": "اضبط box-sizing: border-box"
+ "message": "ما قيمة box-sizing التي تشمل الحشو والحدود في العرض الإجمالي للعنصر؟"
}
]
},
@@ -107,7 +107,7 @@
{
"type": "regex",
"value": "padding:\\s*8px\\s+1rem",
- "message": "اضبط padding: 8px 1rem",
+ "message": "استخدم اختصار padding بقيمتين: عمودي ثم أفقي",
"options": { "caseSensitive": false }
}
]
@@ -129,7 +129,7 @@
{
"type": "regex",
"value": "margin:\\s*0\\s+auto",
- "message": "اضبط margin: 0 auto",
+ "message": "استخدم margin مع كلمة مفتاحية تحسب تلقائياً مسافات متساوية يميناً ويساراً",
"options": { "caseSensitive": false }
}
]
@@ -151,7 +151,7 @@
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "50%" },
- "message": "اضبط border-radius: 50%"
+ "message": "ما نسبة border-radius التي تُنشئ دائرة كاملة من عنصر مربع؟"
}
]
},
@@ -172,18 +172,18 @@
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "اضبط padding: 1rem"
+ "message": "أضف مساحة داخلية لبطاقة الإشعار"
},
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+coral",
- "message": "اضبط border-left: 4px solid coral",
+ "message": "أضف لمسة حدود يسارية باستخدام اختصار border-left",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "4px" },
- "message": "اضبط border-radius: 4px"
+ "message": "دوّر الزوايا قليلاً باستخدام border-radius"
}
]
}
diff --git a/lessons/ar/05-units-variables.json b/lessons/ar/05-units-variables.json
index 1217140..e6614c1 100644
--- a/lessons/ar/05-units-variables.json
+++ b/lessons/ar/05-units-variables.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "max-width", "expected": "40rem" },
- "message": "اضبط max-width: 40rem"
+ "message": "ما الخاصية التي تحدّ من عرض العنصر؟ جرّب قيمة بوحدة rem لطول سطر مقروء."
}
]
},
@@ -43,13 +43,13 @@
{
"type": "contains",
"value": "--brand",
- "message": "عرّف المتغير --brand",
+ "message": "عرّف متغير --brand",
"options": { "caseSensitive": false }
},
{
"type": "contains",
"value": "steelblue",
- "message": "اضبط القيمة على steelblue",
+ "message": "اضبط القيمة إلى steelblue",
"options": { "caseSensitive": false }
}
]
@@ -71,7 +71,7 @@
{
"type": "regex",
"value": "width:\\s*calc\\(\\s*100%\\s*-\\s*200px\\s*\\)",
- "message": "اضبط width: calc(100% - 200px)",
+ "message": "استخدم calc() لطرح عرض الشريط الجانبي الثابت من عرض الحاوية الكامل.",
"options": { "caseSensitive": false }
}
]
@@ -93,7 +93,7 @@
{
"type": "property_value",
"value": { "property": "min-height", "expected": "100vh" },
- "message": "اضبط min-height: 100vh"
+ "message": "ما الخاصية التي تضمن حداً أدنى للارتفاع؟ استخدم وحدة viewport لتغطية الشاشة بالكامل."
}
]
}
diff --git a/lessons/ar/06-transitions-animations.json b/lessons/ar/06-transitions-animations.json
index 9c52658..df994f1 100644
--- a/lessons/ar/06-transitions-animations.json
+++ b/lessons/ar/06-transitions-animations.json
@@ -28,7 +28,7 @@
{
"type": "regex",
"value": "transition:\\s*background-color\\s*0\\.3s",
- "message": "اضبط transition: background-color 0.3s",
+ "message": "حدد أي خاصية تريد تحريكها وكم من الوقت يجب أن تستغرق.",
"options": { "caseSensitive": false }
}
]
@@ -56,7 +56,7 @@
{
"type": "property_value",
"value": { "property": "transition-timing-function", "expected": "ease-in-out" },
- "message": "اضبط التوقيت على ease-in-out"
+ "message": "ما كلمة التسهيل التي تبدأ بطيئة، تتسارع، ثم تبطئ مرة أخرى؟"
}
]
},
@@ -95,7 +95,7 @@
{
"type": "regex",
"value": "animation:.*bounce.*1s.*infinite",
- "message": "طبّق animation: bounce 1s infinite",
+ "message": "استخدم اختصار animation: الاسم، المدة، وعدد التكرار.",
"options": { "caseSensitive": false }
}
]
@@ -117,27 +117,27 @@
{
"type": "property_value",
"value": { "property": "animation-name", "expected": "pulse" },
- "message": "اضبط animation-name: pulse"
+ "message": "ما الخاصية التي تربط العنصر بقاعدة @keyframes مسماة؟"
},
{
"type": "property_value",
"value": { "property": "animation-duration", "expected": "2s" },
- "message": "اضبط animation-duration: 2s"
+ "message": "كم يجب أن تستغرق دورة كاملة من الحركة؟"
},
{
"type": "property_value",
"value": { "property": "animation-delay", "expected": "1s" },
- "message": "اضبط animation-delay: 1s"
+ "message": "ما الخاصية التي تجعل الحركة تنتظر قبل أن تبدأ؟"
},
{
"type": "property_value",
"value": { "property": "animation-iteration-count", "expected": "2" },
- "message": "اضبط animation-iteration-count: 2"
+ "message": "ما الخاصية التي تتحكم في عدد مرات تكرار الحركة؟"
},
{
"type": "property_value",
"value": { "property": "animation-fill-mode", "expected": "forwards" },
- "message": "اضبط animation-fill-mode: forwards"
+ "message": "ما الخاصية التي تُبقي العنصر بتنسيق حالته النهائية بعد انتهاء الحركة؟"
}
]
}
diff --git a/lessons/ar/08-responsive.json b/lessons/ar/08-responsive.json
index 5602b28..5819b56 100644
--- a/lessons/ar/08-responsive.json
+++ b/lessons/ar/08-responsive.json
@@ -22,7 +22,7 @@
{
"type": "regex",
"value": "@media\\s*\\(max-width:\\s*600px\\)",
- "message": "استخدم @media (max-width: 600px)",
+ "message": "ابدأ بقاعدة @media — ما الشرط الذي يستهدف الشاشات بعرض 600px أو أقل؟",
"options": { "caseSensitive": false }
},
{
@@ -34,7 +34,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "lightcoral" },
- "message": "اضبط background: lightcoral",
+ "message": "ما الخاصية التي تغيّر لون خلفية العنصر؟",
"options": { "exact": false }
}
]
@@ -53,7 +53,11 @@
"solution": " font-size: 5vw;",
"previewContainer": "preview-area",
"validations": [
- { "type": "property_value", "value": { "property": "font-size", "expected": "5vw" }, "message": "اضبط font-size: 5vw" }
+ {
+ "type": "property_value",
+ "value": { "property": "font-size", "expected": "5vw" },
+ "message": "ما وحدة CSS التي تتناسب مع عرض viewport؟"
+ }
]
},
{
@@ -73,18 +77,18 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "grid" },
- "message": "اضبط display: grid"
+ "message": "ما وضع العرض الذي يتيح لك تعريف صفوف وأعمدة؟"
},
{
"type": "regex",
"value": "repeat\\(auto-fit,\\s*minmax\\(200px,\\s*1fr\\)\\)",
- "message": "استخدم repeat(auto-fit, minmax(200px, 1fr))",
+ "message": "جرّب repeat() مع auto-fit و minmax() — ما الحد الأدنى والأقصى للحجم لإنشاء أعمدة مرنة؟",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
- "message": "اضبط gap: 1rem"
+ "message": "ما الخاصية التي تضيف مساحة بين عناصر الشبكة؟"
}
]
},
@@ -105,7 +109,7 @@
{
"type": "regex",
"value": "@media\\s*\\(min-width:\\s*768px\\)",
- "message": "استخدم @media (min-width: 768px)",
+ "message": "ما شرط @media الذي يُطبّق الأنماط عندما يكون عرض viewport على الأقل 768px؟",
"options": { "caseSensitive": false }
},
{
@@ -117,7 +121,7 @@
{
"type": "property_value",
"value": { "property": "width", "expected": "250px" },
- "message": "اضبط width: 250px",
+ "message": "ما الخاصية التي تتحكم في عرض الشريط الجانبي على الشاشات الكبيرة؟",
"options": { "exact": false }
}
]
diff --git a/lessons/ar/flexbox.json b/lessons/ar/flexbox.json
index 5338883..431fd46 100644
--- a/lessons/ar/flexbox.json
+++ b/lessons/ar/flexbox.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "flex" },
- "message": "اضبط display: flex"
+ "message": "ما قيمة display التي تحوّل العنصر إلى حاوية صندوق مرن؟"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
- "message": "اضبط gap: 1rem"
+ "message": "ما الخاصية التي تُنشئ تباعداً بين عناصر flex بدون استخدام الهوامش؟"
}
]
},
@@ -64,7 +64,7 @@
{
"type": "property_value",
"value": { "property": "justify-content", "expected": "space-between" },
- "message": "اضبط justify-content: space-between"
+ "message": "ما قيمة justify-content التي تدفع العنصر الأول والأخير إلى الحواف المتقابلة؟"
}
]
},
@@ -85,7 +85,7 @@
{
"type": "property_value",
"value": { "property": "align-items", "expected": "center" },
- "message": "اضبط align-items: center"
+ "message": "ما الخاصية التي تُحاذي عناصر flex على طول المحور المتقاطع؟"
}
]
},
@@ -106,7 +106,7 @@
{
"type": "property_value",
"value": { "property": "flex-wrap", "expected": "wrap" },
- "message": "اضبط flex-wrap: wrap"
+ "message": "ما الخاصية التي تسمح لعناصر flex بالتدفق إلى أسطر متعددة؟"
}
]
},
@@ -127,7 +127,7 @@
{
"type": "property_value",
"value": { "property": "flex", "expected": "1" },
- "message": "اضبط flex: 1"
+ "message": "ما الخاصية التي تجعل عنصر flex ينمو لملء المساحة المتبقية؟"
}
]
}
diff --git a/lessons/de/00-basic-selectors.json b/lessons/de/00-basic-selectors.json
index b9ff9b3..6c06fe7 100644
--- a/lessons/de/00-basic-selectors.json
+++ b/lessons/de/00-basic-selectors.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
- "message": "Füge color: coral; hinzu"
+ "message": "Welche Eigenschaft ändert die Textfarbe?"
}
]
},
@@ -43,12 +43,12 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "lavender" },
- "message": "Füge background: lavender; hinzu"
+ "message": "Welche Eigenschaft steuert die Hintergrundfarbe?"
},
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Füge padding: 1rem; hinzu"
+ "message": "Das Element benötigt auch Innenabstand -- überprüfe die padding-Eigenschaft"
}
]
},
@@ -74,7 +74,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "steelblue" },
- "message": "Setze color: steelblue"
+ "message": "Überprüfe die color-Eigenschaft -- welcher Farbwert wurde in der Beschreibung genannt?"
}
]
},
@@ -100,7 +100,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
- "message": "Setze color: coral"
+ "message": "Überprüfe die color-Eigenschaft -- welche Farbe sollen die Links haben?"
}
]
},
@@ -126,7 +126,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "tomato" },
- "message": "Setze background: tomato"
+ "message": "Überprüfe die background-Eigenschaft -- welche Farbe soll das Badge haben?"
}
]
},
@@ -152,7 +152,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "steelblue" },
- "message": "Setze background: steelblue"
+ "message": "Überprüfe die background-Eigenschaft -- welche Farbe soll der primäre Button haben?"
}
]
},
@@ -178,7 +178,7 @@
{
"type": "property_value",
"value": { "property": "text-decoration", "expected": "none" },
- "message": "Setze text-decoration: none"
+ "message": "Welche Eigenschaft entfernt die Unterstreichung von Links?"
}
]
},
@@ -199,7 +199,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "steelblue" },
- "message": "Setze color: steelblue"
+ "message": "Welche Eigenschaft ändert die Textfarbe der Überschriften?"
}
]
},
@@ -225,7 +225,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "white" },
- "message": "Setze color: white"
+ "message": "Überprüfe die color-Eigenschaft -- welche Farbe passt zu einem dunklen Hintergrund?"
}
]
},
@@ -251,7 +251,7 @@
{
"type": "property_value",
"value": { "property": "font-size", "expected": "0.9rem" },
- "message": "Setze font-size: 0.9rem"
+ "message": "Welche Eigenschaft steuert die Schriftgröße?"
}
]
}
diff --git a/lessons/de/01-advanced-selectors.json b/lessons/de/01-advanced-selectors.json
index f44bfcd..a56ea88 100644
--- a/lessons/de/01-advanced-selectors.json
+++ b/lessons/de/01-advanced-selectors.json
@@ -38,7 +38,7 @@
"property": "background-color",
"expected": "lightblue"
},
- "message": "Setze die Hintergrundfarbe auf lightblue"
+ "message": "Überprüfe die background-color-Eigenschaft -- welche Farbe sollen die Text-Eingabefelder haben?"
},
{
"type": "regex",
@@ -56,7 +56,7 @@
"property": "border",
"expected": "2px solid blue"
},
- "message": "Setze den Rahmen auf 2px solid blue"
+ "message": "Das Element benötigt einen Rahmen -- überprüfe die border-Eigenschaft"
},
{
"type": "regex",
@@ -101,7 +101,7 @@
"property": "color",
"expected": "green"
},
- "message": "Setze die Textfarbe auf green"
+ "message": "Überprüfe die color-Eigenschaft -- welche Farbe kennzeichnet sichere Links?"
},
{
"type": "contains",
@@ -114,7 +114,7 @@
"property": "text-decoration",
"expected": "underline"
},
- "message": "Setze text-decoration auf underline, um HTTPS-Links zu unterstreichen"
+ "message": "Welcher text-decoration-Wert macht Links visuell hervorgehoben?"
},
{
"type": "regex",
@@ -159,7 +159,7 @@
"property": "background-color",
"expected": "cornflowerblue"
},
- "message": "Setze background-color auf cornflowerblue für das Hauptmenü-Styling"
+ "message": "Überprüfe die background-color-Eigenschaft für die Hauptmenüpunkte"
},
{
"type": "contains",
@@ -172,7 +172,7 @@
"property": "color",
"expected": "white"
},
- "message": "Setze die Textfarbe auf white für Kontrast gegen den blauen Hintergrund"
+ "message": "Welche Textfarbe sorgt für guten Kontrast auf einem blauen Hintergrund?"
},
{
"type": "regex",
@@ -217,7 +217,7 @@
"property": "text-decoration",
"expected": "none"
},
- "message": "Setze text-decoration auf none"
+ "message": "Welcher text-decoration-Wert entfernt die Unterstreichung?"
},
{
"type": "contains",
@@ -230,7 +230,7 @@
"property": "color",
"expected": "blue"
},
- "message": "Setze color auf blue"
+ "message": "Überprüfe die color-Eigenschaft für die Links"
},
{
"type": "regex",
@@ -275,7 +275,7 @@
"property": "margin-top",
"expected": "0"
},
- "message": "Setze margin-top auf 0"
+ "message": "Welcher Wert bei margin-top entfernt den oberen Abstand?"
},
{
"type": "contains",
@@ -288,7 +288,7 @@
"property": "font-style",
"expected": "italic"
},
- "message": "Setze font-style auf italic"
+ "message": "Welcher font-style-Wert macht den Text kursiv?"
},
{
"type": "regex",
@@ -333,7 +333,7 @@
"property": "color",
"expected": "gray"
},
- "message": "Setze color auf gray"
+ "message": "Überprüfe die color-Eigenschaft -- welche Farbe sollen die Absätze haben?"
},
{
"type": "contains",
@@ -346,7 +346,7 @@
"property": "padding-left",
"expected": "20px"
},
- "message": "Setze padding-left auf 20px"
+ "message": "Das Element benötigt eine Einrückung -- überprüfe die padding-left-Eigenschaft"
},
{
"type": "regex",
@@ -391,7 +391,7 @@
"property": "background-color",
"expected": "darkblue"
},
- "message": "Setze background-color auf darkblue"
+ "message": "Welche Hintergrundfarbe soll der Button beim Hover haben?"
},
{
"type": "contains",
@@ -404,7 +404,7 @@
"property": "color",
"expected": "white"
},
- "message": "Setze color auf white"
+ "message": "Welche Textfarbe sorgt für Kontrast auf dunklem Hintergrund?"
},
{
"type": "regex",
@@ -449,7 +449,7 @@
"property": "font-weight",
"expected": "bold"
},
- "message": "Setze font-weight auf bold"
+ "message": "Welcher font-weight-Wert macht Text fett?"
},
{
"type": "contains",
@@ -462,7 +462,7 @@
"property": "margin-top",
"expected": "0"
},
- "message": "Setze margin-top auf 0"
+ "message": "Welcher Wert entfernt den oberen Abstand vollständig?"
},
{
"type": "regex",
diff --git a/lessons/de/01-box-model.json b/lessons/de/01-box-model.json
index 641529c..e72a4c4 100644
--- a/lessons/de/01-box-model.json
+++ b/lessons/de/01-box-model.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Setze padding: 1rem"
+ "message": "Welche Eigenschaft steuert den Innenabstand zwischen Inhalt und Rahmen?"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+steelblue",
- "message": "Setze border-left: 4px solid steelblue",
+ "message": "Überprüfe die border-left-Eigenschaft -- welche drei Werte braucht sie?",
"options": { "caseSensitive": false }
}
]
@@ -65,7 +65,7 @@
{
"type": "property_value",
"value": { "property": "margin-bottom", "expected": "1rem" },
- "message": "Setze margin-bottom: 1rem"
+ "message": "Welche Eigenschaft steuert den Außenabstand nach unten?"
}
]
},
@@ -86,7 +86,7 @@
{
"type": "property_value",
"value": { "property": "box-sizing", "expected": "border-box" },
- "message": "Setze box-sizing: border-box"
+ "message": "Welcher box-sizing-Wert bezieht Padding und Rahmen in die Breite ein?"
}
]
},
@@ -107,7 +107,7 @@
{
"type": "regex",
"value": "padding:\\s*8px\\s+1rem",
- "message": "Setze padding: 8px 1rem",
+ "message": "Überprüfe die padding-Kurzschreibweise -- zwei Werte setzen vertikal und horizontal",
"options": { "caseSensitive": false }
}
]
@@ -129,7 +129,7 @@
{
"type": "regex",
"value": "margin:\\s*0\\s+auto",
- "message": "Setze margin: 0 auto",
+ "message": "Welche margin-Kurzschreibweise zentriert ein Block-Element horizontal?",
"options": { "caseSensitive": false }
}
]
@@ -151,7 +151,7 @@
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "50%" },
- "message": "Setze border-radius: 50%"
+ "message": "Welcher border-radius-Wert macht ein quadratisches Element rund?"
}
]
},
@@ -172,18 +172,18 @@
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Setze padding: 1rem"
+ "message": "Das Element benötigt Innenabstand -- überprüfe die padding-Eigenschaft"
},
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+coral",
- "message": "Setze border-left: 4px solid coral",
+ "message": "Überprüfe die border-left-Eigenschaft -- sie braucht Breite, Stil und Farbe",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "4px" },
- "message": "Setze border-radius: 4px"
+ "message": "Das Element benötigt abgerundete Ecken -- überprüfe die border-radius-Eigenschaft"
}
]
}
diff --git a/lessons/de/05-units-variables.json b/lessons/de/05-units-variables.json
index 70e7556..95e9780 100644
--- a/lessons/de/05-units-variables.json
+++ b/lessons/de/05-units-variables.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "max-width", "expected": "40rem" },
- "message": "Setze max-width: 40rem"
+ "message": "Welche Eigenschaft begrenzt die maximale Breite eines Elements?"
}
]
},
@@ -49,7 +49,7 @@
{
"type": "contains",
"value": "steelblue",
- "message": "Setze den Wert auf steelblue",
+ "message": "Welche Farbe soll die Variable haben?",
"options": { "caseSensitive": false }
}
]
@@ -71,7 +71,7 @@
{
"type": "regex",
"value": "width:\\s*calc\\(\\s*100%\\s*-\\s*200px\\s*\\)",
- "message": "Setze width: calc(100% - 200px)",
+ "message": "Überprüfe die width-Eigenschaft -- wie berechnest du den verbleibenden Platz nach der Sidebar?",
"options": { "caseSensitive": false }
}
]
@@ -93,7 +93,7 @@
{
"type": "property_value",
"value": { "property": "min-height", "expected": "100vh" },
- "message": "Setze min-height: 100vh"
+ "message": "Welche Eigenschaft setzt die Mindesthöhe? Welche Viewport-Einheit entspricht 100% der Fensterhöhe?"
}
]
}
diff --git a/lessons/de/06-transitions-animations.json b/lessons/de/06-transitions-animations.json
index f9ae449..74a1fd7 100644
--- a/lessons/de/06-transitions-animations.json
+++ b/lessons/de/06-transitions-animations.json
@@ -28,7 +28,7 @@
{
"type": "regex",
"value": "transition:\\s*background-color\\s*0\\.3s",
- "message": "Setze transition: background-color 0.3s",
+ "message": "Überprüfe die transition-Eigenschaft -- welche CSS-Eigenschaft soll sanft übergehen und wie lange?",
"options": { "caseSensitive": false }
}
]
@@ -56,7 +56,7 @@
{
"type": "property_value",
"value": { "property": "transition-timing-function", "expected": "ease-in-out" },
- "message": "Setze timing auf ease-in-out"
+ "message": "Welche Timing-Funktion startet und endet langsam?"
}
]
},
@@ -117,27 +117,27 @@
{
"type": "property_value",
"value": { "property": "animation-name", "expected": "pulse" },
- "message": "Setze animation-name: pulse"
+ "message": "Welche Animation soll angewendet werden? Überprüfe den @keyframes-Namen."
},
{
"type": "property_value",
"value": { "property": "animation-duration", "expected": "2s" },
- "message": "Setze animation-duration: 2s"
+ "message": "Welche Eigenschaft steuert die Dauer der Animation?"
},
{
"type": "property_value",
"value": { "property": "animation-delay", "expected": "1s" },
- "message": "Setze animation-delay: 1s"
+ "message": "Welche Eigenschaft verzögert den Start der Animation?"
},
{
"type": "property_value",
"value": { "property": "animation-iteration-count", "expected": "2" },
- "message": "Setze animation-iteration-count: 2"
+ "message": "Welche Eigenschaft steuert, wie oft die Animation wiederholt wird?"
},
{
"type": "property_value",
"value": { "property": "animation-fill-mode", "expected": "forwards" },
- "message": "Setze animation-fill-mode: forwards"
+ "message": "Welcher animation-fill-mode-Wert behält den Endzustand bei?"
}
]
}
diff --git a/lessons/de/08-responsive.json b/lessons/de/08-responsive.json
index 9bd9c55..7c4a5d2 100644
--- a/lessons/de/08-responsive.json
+++ b/lessons/de/08-responsive.json
@@ -34,7 +34,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "lightcoral" },
- "message": "Setze background: lightcoral",
+ "message": "Überprüfe die background-Eigenschaft innerhalb der Media Query",
"options": { "exact": false }
}
]
@@ -53,7 +53,11 @@
"solution": " font-size: 5vw;",
"previewContainer": "preview-area",
"validations": [
- { "type": "property_value", "value": { "property": "font-size", "expected": "5vw" }, "message": "Setze font-size: 5vw" }
+ {
+ "type": "property_value",
+ "value": { "property": "font-size", "expected": "5vw" },
+ "message": "Welche Eigenschaft steuert die Schriftgröße? Welche Viewport-Einheit skaliert mit der Breite?"
+ }
]
},
{
@@ -73,7 +77,7 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "grid" },
- "message": "Setze display: grid"
+ "message": "Welcher Display-Wert aktiviert das CSS-Grid-Layout?"
},
{
"type": "regex",
@@ -84,7 +88,7 @@
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
- "message": "Setze gap: 1rem"
+ "message": "Welche Eigenschaft steuert den Abstand zwischen Grid-Zellen?"
}
]
},
@@ -117,7 +121,7 @@
{
"type": "property_value",
"value": { "property": "width", "expected": "250px" },
- "message": "Setze width: 250px",
+ "message": "Überprüfe die width-Eigenschaft für die Sidebar",
"options": { "exact": false }
}
]
diff --git a/lessons/de/10-tailwind-basics.json b/lessons/de/10-tailwind-basics.json
index ebee021..29dae84 100644
--- a/lessons/de/10-tailwind-basics.json
+++ b/lessons/de/10-tailwind-basics.json
@@ -20,7 +20,7 @@
{
"type": "contains_class",
"value": "bg-blue-500",
- "message": "Füge die bg-blue-500-Klasse für einen blauen Hintergrund hinzu."
+ "message": "Welche Tailwind-Klasse setzt eine blaue Hintergrundfarbe? Denke an das bg-{farbe}-{abstufung}-Muster."
}
]
},
@@ -38,22 +38,22 @@
{
"type": "contains_class",
"value": "bg-white",
- "message": "Füge bg-white hinzu, um die Hintergrundfarbe auf weiß zu setzen."
+ "message": "Das Element benötigt einen weißen Hintergrund -- welches bg--Utility passt?"
},
{
"type": "contains_class",
"value": "p-4",
- "message": "Füge p-4 hinzu, um 1rem Padding auf allen Seiten anzuwenden."
+ "message": "Welches p--Utility erzeugt 1rem Padding auf allen Seiten?"
},
{
"type": "contains_class",
"value": "rounded",
- "message": "Füge rounded hinzu, um einen border-radius von 0.25rem anzuwenden."
+ "message": "Welche Klasse fügt abgerundete Ecken hinzu?"
},
{
"type": "contains_class",
"value": "shadow-sm",
- "message": "Füge shadow-sm hinzu, um einen kleinen Schlagschatten anzuwenden."
+ "message": "Das Element benötigt einen kleinen Schatten -- welches shadow--Utility passt?"
}
]
},
@@ -71,17 +71,17 @@
{
"type": "contains_class",
"value": "text-blue-600",
- "message": "Füge text-blue-600 hinzu, um den Text blau zu machen"
+ "message": "Welches text--Utility setzt eine blaue Textfarbe? Denke an das text-{farbe}-{abstufung}-Muster."
},
{
"type": "contains_class",
"value": "text-2xl",
- "message": "Füge text-2xl hinzu, um die Schriftgröße auf 1.5rem zu erhöhen"
+ "message": "Welches text--Utility setzt die Schriftgröße auf 1.5rem?"
},
{
"type": "contains_class",
"value": "font-bold",
- "message": "Füge font-bold hinzu, um den Text fett zu machen (font-weight: 700)"
+ "message": "Welches font--Utility macht den Text fett?"
}
]
},
@@ -99,17 +99,17 @@
{
"type": "contains_class",
"value": "px-6",
- "message": "Füge px-6 für horizontales Padding hinzu (1.5rem links und rechts)"
+ "message": "Welches px--Utility erzeugt 1.5rem horizontales Padding?"
},
{
"type": "contains_class",
"value": "py-3",
- "message": "Füge py-3 für vertikales Padding hinzu (0.75rem oben und unten)"
+ "message": "Welches py--Utility erzeugt 0.75rem vertikales Padding?"
},
{
"type": "contains_class",
"value": "mx-auto",
- "message": "Füge mx-auto hinzu, um den Button horizontal zu zentrieren"
+ "message": "Welches mx--Utility zentriert ein Element horizontal?"
}
]
},
@@ -127,32 +127,32 @@
{
"type": "contains_class",
"value": "w-full",
- "message": "Füge w-full für 100% Breite auf Mobil hinzu"
+ "message": "Welches Breiten-Utility macht das Element auf Mobil 100% breit?"
},
{
"type": "contains_class",
"value": "md:w-1/2",
- "message": "Füge md:w-1/2 für 50% Breite auf Tablet und größer hinzu"
+ "message": "Welches responsive Breiten-Utility setzt 50% ab dem md:-Breakpoint?"
},
{
"type": "contains_class",
"value": "lg:w-1/3",
- "message": "Füge lg:w-1/3 für 33.33% Breite auf Desktop und größer hinzu"
+ "message": "Welches responsive Breiten-Utility setzt 33.33% ab dem lg:-Breakpoint?"
},
{
"type": "contains_class",
"value": "text-lg",
- "message": "Füge text-lg für die Basis-Textgröße hinzu"
+ "message": "Welches text--Utility setzt die Basis-Textgröße auf 1.125rem?"
},
{
"type": "contains_class",
"value": "md:text-xl",
- "message": "Füge md:text-xl für größeren Text auf Tablets hinzu"
+ "message": "Welches responsive Text-Utility setzt eine größere Schrift ab dem md:-Breakpoint?"
},
{
"type": "contains_class",
"value": "lg:text-2xl",
- "message": "Füge lg:text-2xl für noch größeren Text auf Desktop hinzu"
+ "message": "Welches responsive Text-Utility setzt die größte Schrift ab dem lg:-Breakpoint?"
}
]
}
diff --git a/lessons/de/flexbox.json b/lessons/de/flexbox.json
index a66f6b3..c37867e 100644
--- a/lessons/de/flexbox.json
+++ b/lessons/de/flexbox.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "flex" },
- "message": "Setze display: flex"
+ "message": "Welcher Display-Wert macht ein Element zu einem flexiblen Box-Container?"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
- "message": "Setze gap: 1rem"
+ "message": "Welche Eigenschaft erzeugt Abstände zwischen Flex-Items ohne Margins?"
}
]
},
@@ -64,7 +64,7 @@
{
"type": "property_value",
"value": { "property": "justify-content", "expected": "space-between" },
- "message": "Setze justify-content: space-between"
+ "message": "Welcher justify-content-Wert schiebt das erste und letzte Element an gegenüberliegende Ränder?"
}
]
},
@@ -85,7 +85,7 @@
{
"type": "property_value",
"value": { "property": "align-items", "expected": "center" },
- "message": "Setze align-items: center"
+ "message": "Welche Eigenschaft richtet Flex-Items entlang der Querachse aus?"
}
]
},
@@ -106,7 +106,7 @@
{
"type": "property_value",
"value": { "property": "flex-wrap", "expected": "wrap" },
- "message": "Setze flex-wrap: wrap"
+ "message": "Welche Eigenschaft erlaubt Flex-Items, auf mehrere Zeilen umzubrechen?"
}
]
},
@@ -127,7 +127,7 @@
{
"type": "property_value",
"value": { "property": "flex", "expected": "1" },
- "message": "Setze flex: 1"
+ "message": "Welche Eigenschaft lässt ein Flex-Item wachsen, um den verbleibenden Platz zu füllen?"
}
]
}
diff --git a/lessons/es/00-basic-selectors.json b/lessons/es/00-basic-selectors.json
index 32d2462..47cece1 100644
--- a/lessons/es/00-basic-selectors.json
+++ b/lessons/es/00-basic-selectors.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
- "message": "Añade color: coral;"
+ "message": "¿Qué propiedad controla el color del texto?"
}
]
},
@@ -43,12 +43,12 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "lavender" },
- "message": "Añade background: lavender;"
+ "message": "Revisa la propiedad background"
},
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Añade padding: 1rem;"
+ "message": "La tarjeta necesita espacio dentro de sus bordes"
}
]
},
@@ -74,7 +74,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "steelblue" },
- "message": "Establece color: steelblue"
+ "message": "¿Qué propiedad cambia el color del texto?"
}
]
},
@@ -100,7 +100,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
- "message": "Establece color: coral"
+ "message": "¿Qué valor da un color cálido, rojo-anaranjado?"
}
]
},
@@ -126,7 +126,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "tomato" },
- "message": "Establece background: tomato"
+ "message": "El badge necesita un fondo rojo brillante"
}
]
},
@@ -152,7 +152,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "steelblue" },
- "message": "Establece background: steelblue"
+ "message": "¿Qué propiedad establece el color de relleno del botón?"
}
]
},
@@ -178,7 +178,7 @@
{
"type": "property_value",
"value": { "property": "text-decoration", "expected": "none" },
- "message": "Establece text-decoration: none"
+ "message": "¿Qué propiedad controla el subrayado de los enlaces?"
}
]
},
@@ -199,7 +199,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "steelblue" },
- "message": "Establece color: steelblue"
+ "message": "Revisa la propiedad color"
}
]
},
@@ -225,7 +225,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "white" },
- "message": "Establece color: white"
+ "message": "Los enlaces necesitan destacar sobre el fondo azul"
}
]
},
@@ -251,7 +251,7 @@
{
"type": "property_value",
"value": { "property": "font-size", "expected": "0.9rem" },
- "message": "Establece font-size: 0.9rem"
+ "message": "Revisa la propiedad font-size — el texto debería ser ligeramente más pequeño"
}
]
}
diff --git a/lessons/es/01-box-model.json b/lessons/es/01-box-model.json
index 6a6c3c8..462aae5 100644
--- a/lessons/es/01-box-model.json
+++ b/lessons/es/01-box-model.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Establece padding: 1rem"
+ "message": "¿Qué propiedad añade espacio entre el contenido de un elemento y su borde?"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+steelblue",
- "message": "Establece border-left: 4px solid steelblue",
+ "message": "Usa el atajo border-left con valores de ancho, estilo y color",
"options": { "caseSensitive": false }
}
]
@@ -65,7 +65,7 @@
{
"type": "property_value",
"value": { "property": "margin-bottom", "expected": "1rem" },
- "message": "Establece margin-bottom: 1rem"
+ "message": "¿Qué propiedad crea espacio debajo de un elemento, separándolo de sus vecinos?"
}
]
},
@@ -86,7 +86,7 @@
{
"type": "property_value",
"value": { "property": "box-sizing", "expected": "border-box" },
- "message": "Establece box-sizing: border-box"
+ "message": "¿Qué valor de box-sizing incluye padding y borde en el ancho total del elemento?"
}
]
},
@@ -107,7 +107,7 @@
{
"type": "regex",
"value": "padding:\\s*8px\\s+1rem",
- "message": "Establece padding: 8px 1rem",
+ "message": "Usa el atajo padding con dos valores: vertical y luego horizontal",
"options": { "caseSensitive": false }
}
]
@@ -129,7 +129,7 @@
{
"type": "regex",
"value": "margin:\\s*0\\s+auto",
- "message": "Establece margin: 0 auto",
+ "message": "Usa margin con una palabra clave que calcula automáticamente espaciado igual a izquierda y derecha",
"options": { "caseSensitive": false }
}
]
@@ -151,7 +151,7 @@
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "50%" },
- "message": "Establece border-radius: 50%"
+ "message": "¿Qué porcentaje de border-radius crea un círculo perfecto a partir de un elemento cuadrado?"
}
]
},
@@ -172,18 +172,18 @@
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Establece padding: 1rem"
+ "message": "El elemento necesita espacio interior"
},
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+coral",
- "message": "Establece border-left: 4px solid coral",
+ "message": "Añade un acento de borde izquierdo usando el atajo border-left",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "4px" },
- "message": "Establece border-radius: 4px"
+ "message": "Redondea las esquinas ligeramente con border-radius"
}
]
}
diff --git a/lessons/es/05-units-variables.json b/lessons/es/05-units-variables.json
index 110d2f2..c551dee 100644
--- a/lessons/es/05-units-variables.json
+++ b/lessons/es/05-units-variables.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "max-width", "expected": "40rem" },
- "message": "Establece max-width: 40rem"
+ "message": "¿Qué propiedad limita el ancho de un elemento? Prueba un valor en rem para una longitud de línea legible."
}
]
},
@@ -49,7 +49,7 @@
{
"type": "contains",
"value": "steelblue",
- "message": "Establece el valor a steelblue",
+ "message": "Asigna el valor steelblue a la variable",
"options": { "caseSensitive": false }
}
]
@@ -71,7 +71,7 @@
{
"type": "regex",
"value": "width:\\s*calc\\(\\s*100%\\s*-\\s*200px\\s*\\)",
- "message": "Establece width: calc(100% - 200px)",
+ "message": "Usa calc() para restar el ancho fijo de la barra lateral del ancho total del contenedor.",
"options": { "caseSensitive": false }
}
]
@@ -93,7 +93,7 @@
{
"type": "property_value",
"value": { "property": "min-height", "expected": "100vh" },
- "message": "Establece min-height: 100vh"
+ "message": "¿Qué propiedad asegura una altura mínima? Usa una unidad de viewport para cobertura de pantalla completa."
}
]
}
diff --git a/lessons/es/06-transitions-animations.json b/lessons/es/06-transitions-animations.json
index 89de698..260ebd8 100644
--- a/lessons/es/06-transitions-animations.json
+++ b/lessons/es/06-transitions-animations.json
@@ -28,7 +28,7 @@
{
"type": "regex",
"value": "transition:\\s*background-color\\s*0\\.3s",
- "message": "Establece transition: background-color 0.3s",
+ "message": "Especifica qué propiedad transicionar y cuánto debe durar.",
"options": { "caseSensitive": false }
}
]
@@ -56,7 +56,7 @@
{
"type": "property_value",
"value": { "property": "transition-timing-function", "expected": "ease-in-out" },
- "message": "Establece timing a ease-in-out"
+ "message": "¿Qué palabra clave de easing empieza lento, acelera, y luego desacelera de nuevo?"
}
]
},
@@ -95,7 +95,7 @@
{
"type": "regex",
"value": "animation:.*bounce.*1s.*infinite",
- "message": "Aplica animation: bounce 1s infinite",
+ "message": "Usa el atajo animation: nombre, duración y número de repeticiones.",
"options": { "caseSensitive": false }
}
]
@@ -117,27 +117,27 @@
{
"type": "property_value",
"value": { "property": "animation-name", "expected": "pulse" },
- "message": "Establece animation-name: pulse"
+ "message": "¿Qué propiedad vincula un elemento a una regla @keyframes nombrada?"
},
{
"type": "property_value",
"value": { "property": "animation-duration", "expected": "2s" },
- "message": "Establece animation-duration: 2s"
+ "message": "¿Cuánto debe durar un ciclo completo de la animación?"
},
{
"type": "property_value",
"value": { "property": "animation-delay", "expected": "1s" },
- "message": "Establece animation-delay: 1s"
+ "message": "¿Qué propiedad hace que la animación espere antes de comenzar?"
},
{
"type": "property_value",
"value": { "property": "animation-iteration-count", "expected": "2" },
- "message": "Establece animation-iteration-count: 2"
+ "message": "¿Qué propiedad controla cuántas veces se repite la animación?"
},
{
"type": "property_value",
"value": { "property": "animation-fill-mode", "expected": "forwards" },
- "message": "Establece animation-fill-mode: forwards"
+ "message": "¿Qué propiedad mantiene el elemento con los estilos de su último keyframe después de que termina la animación?"
}
]
}
diff --git a/lessons/es/08-responsive.json b/lessons/es/08-responsive.json
index 3612a6c..e64b1c9 100644
--- a/lessons/es/08-responsive.json
+++ b/lessons/es/08-responsive.json
@@ -22,7 +22,7 @@
{
"type": "regex",
"value": "@media\\s*\\(max-width:\\s*600px\\)",
- "message": "Usa @media (max-width: 600px)",
+ "message": "Empieza con una regla @media — ¿qué condición apunta a pantallas de 600px de ancho o menos?",
"options": { "caseSensitive": false }
},
{
@@ -34,7 +34,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "lightcoral" },
- "message": "Establece background: lightcoral",
+ "message": "¿Qué propiedad cambia el color de fondo del elemento?",
"options": { "exact": false }
}
]
@@ -56,7 +56,7 @@
{
"type": "property_value",
"value": { "property": "font-size", "expected": "5vw" },
- "message": "Establece font-size: 5vw"
+ "message": "¿Qué unidad CSS escala en relación al ancho del viewport?"
}
]
},
@@ -77,18 +77,18 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "grid" },
- "message": "Establece display: grid"
+ "message": "¿Qué modo de display permite definir filas y columnas?"
},
{
"type": "regex",
"value": "repeat\\(auto-fit,\\s*minmax\\(200px,\\s*1fr\\)\\)",
- "message": "Usa repeat(auto-fit, minmax(200px, 1fr))",
+ "message": "Prueba repeat() con auto-fit y minmax() — ¿qué tamaños mínimo y máximo crean columnas flexibles?",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
- "message": "Establece gap: 1rem"
+ "message": "¿Qué propiedad añade espacio entre los elementos del grid?"
}
]
},
@@ -109,7 +109,7 @@
{
"type": "regex",
"value": "@media\\s*\\(min-width:\\s*768px\\)",
- "message": "Usa @media (min-width: 768px)",
+ "message": "¿Qué condición @media aplica estilos cuando el viewport tiene al menos 768px de ancho?",
"options": { "caseSensitive": false }
},
{
@@ -121,7 +121,7 @@
{
"type": "property_value",
"value": { "property": "width", "expected": "250px" },
- "message": "Establece width: 250px",
+ "message": "¿Qué propiedad controla el ancho de la barra lateral en pantallas más grandes?",
"options": { "exact": false }
}
]
diff --git a/lessons/es/flexbox.json b/lessons/es/flexbox.json
index 5c2270d..c52f069 100644
--- a/lessons/es/flexbox.json
+++ b/lessons/es/flexbox.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "flex" },
- "message": "Establece display: flex"
+ "message": "¿Qué valor de display convierte un elemento en un contenedor de caja flexible?"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
- "message": "Establece gap: 1rem"
+ "message": "¿Qué propiedad crea espaciado entre elementos flex sin usar márgenes?"
}
]
},
@@ -64,7 +64,7 @@
{
"type": "property_value",
"value": { "property": "justify-content", "expected": "space-between" },
- "message": "Establece justify-content: space-between"
+ "message": "¿Qué valor de justify-content empuja el primer y último elemento a los extremos opuestos?"
}
]
},
@@ -85,7 +85,7 @@
{
"type": "property_value",
"value": { "property": "align-items", "expected": "center" },
- "message": "Establece align-items: center"
+ "message": "¿Qué propiedad alinea los elementos flex a lo largo del eje transversal?"
}
]
},
@@ -106,7 +106,7 @@
{
"type": "property_value",
"value": { "property": "flex-wrap", "expected": "wrap" },
- "message": "Establece flex-wrap: wrap"
+ "message": "¿Qué propiedad permite que los elementos flex fluyan a múltiples líneas?"
}
]
},
@@ -127,7 +127,7 @@
{
"type": "property_value",
"value": { "property": "flex", "expected": "1" },
- "message": "Establece flex: 1"
+ "message": "¿Qué propiedad hace que un elemento flex crezca para llenar el espacio restante?"
}
]
}
diff --git a/lessons/flexbox.json b/lessons/flexbox.json
index 6646dd2..820afe1 100644
--- a/lessons/flexbox.json
+++ b/lessons/flexbox.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "flex" },
- "message": "Set display: flex"
+ "message": "Which display value turns an element into a flexible box container?"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
- "message": "Set gap: 1rem"
+ "message": "Which property creates spacing between flex items without using margins?"
}
]
},
@@ -64,7 +64,7 @@
{
"type": "property_value",
"value": { "property": "justify-content", "expected": "space-between" },
- "message": "Set justify-content: space-between"
+ "message": "Which justify-content value pushes the first and last items to opposite edges?"
}
]
},
@@ -85,7 +85,7 @@
{
"type": "property_value",
"value": { "property": "align-items", "expected": "center" },
- "message": "Set align-items: center"
+ "message": "Which property aligns flex items along the cross axis?"
}
]
},
@@ -106,7 +106,7 @@
{
"type": "property_value",
"value": { "property": "flex-wrap", "expected": "wrap" },
- "message": "Set flex-wrap: wrap"
+ "message": "Which property allows flex items to flow onto multiple lines?"
}
]
},
@@ -127,7 +127,7 @@
{
"type": "property_value",
"value": { "property": "flex", "expected": "1" },
- "message": "Set flex: 1"
+ "message": "Which property makes a flex item grow to fill the remaining space?"
}
]
}
diff --git a/lessons/grid.json b/lessons/grid.json
index fcc141c..6dc2183 100644
--- a/lessons/grid.json
+++ b/lessons/grid.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "grid" },
- "message": "Set display: grid"
+ "message": "Which display value activates the CSS Grid layout system?"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "regex",
"value": "grid-template-columns:\\s*repeat\\(\\s*3\\s*,\\s*1fr\\s*\\)",
- "message": "Set grid-template-columns: repeat(3, 1fr)",
+ "message": "Which CSS property defines column sizes in a grid? Use repeat() with the fr unit for equal columns.",
"options": { "caseSensitive": false }
}
]
@@ -65,7 +65,7 @@
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
- "message": "Set gap: 1rem"
+ "message": "Which CSS property adds spacing between grid cells without affecting the outer edges?"
}
]
},
@@ -86,7 +86,7 @@
{
"type": "regex",
"value": "grid-column:\\s*span\\s+2",
- "message": "Set grid-column: span 2",
+ "message": "Which CSS property makes a grid item stretch across multiple columns? Use the span keyword.",
"options": { "caseSensitive": false }
}
]
@@ -108,7 +108,7 @@
{
"type": "regex",
"value": "grid-template-columns:\\s*repeat\\(\\s*auto-fit\\s*,\\s*minmax\\(\\s*150px\\s*,\\s*1fr\\s*\\)\\s*\\)",
- "message": "Set grid-template-columns: repeat(auto-fit, minmax(150px, 1fr))",
+ "message": "Which CSS property creates responsive columns? Combine auto-fit with minmax() for flexible sizing.",
"options": { "caseSensitive": false }
}
]
diff --git a/lessons/pl/00-basic-selectors.json b/lessons/pl/00-basic-selectors.json
index 5c43a8f..8feaef9 100644
--- a/lessons/pl/00-basic-selectors.json
+++ b/lessons/pl/00-basic-selectors.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
- "message": "Dodaj color: coral;"
+ "message": "Która właściwość kontroluje kolor tekstu?"
}
]
},
@@ -43,12 +43,12 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "lavender" },
- "message": "Dodaj background: lavender;"
+ "message": "Sprawdź właściwość background — jaki kolor potrzebuje karta?"
},
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Dodaj padding: 1rem;"
+ "message": "Element potrzebuje wewnętrznej przestrzeni — sprawdź właściwość padding"
}
]
},
@@ -74,7 +74,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "steelblue" },
- "message": "Ustaw color: steelblue"
+ "message": "Która właściwość kontroluje kolor tekstu?"
}
]
},
@@ -100,7 +100,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
- "message": "Ustaw color: coral"
+ "message": "Sprawdź właściwość color — jaki kolor potrzebują linki?"
}
]
},
@@ -126,7 +126,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "tomato" },
- "message": "Ustaw background: tomato"
+ "message": "Sprawdź właściwość background — jaki kolor potrzebuje badge?"
}
]
},
@@ -152,7 +152,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "steelblue" },
- "message": "Ustaw background: steelblue"
+ "message": "Sprawdź właściwość background — jaki kolor potrzebuje przycisk?"
}
]
},
@@ -178,7 +178,7 @@
{
"type": "property_value",
"value": { "property": "text-decoration", "expected": "none" },
- "message": "Ustaw text-decoration: none"
+ "message": "Która właściwość kontroluje podkreślenie linków?"
}
]
},
@@ -199,7 +199,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "steelblue" },
- "message": "Ustaw color: steelblue"
+ "message": "Która właściwość kontroluje kolor tekstu nagłówków?"
}
]
},
@@ -225,7 +225,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "white" },
- "message": "Ustaw color: white"
+ "message": "Sprawdź właściwość color — jaki kolor potrzebują linki nawigacji?"
}
]
},
@@ -251,7 +251,7 @@
{
"type": "property_value",
"value": { "property": "font-size", "expected": "0.9rem" },
- "message": "Ustaw font-size: 0.9rem"
+ "message": "Która właściwość kontroluje rozmiar tekstu?"
}
]
}
diff --git a/lessons/pl/01-box-model.json b/lessons/pl/01-box-model.json
index 55db4fc..297c7c4 100644
--- a/lessons/pl/01-box-model.json
+++ b/lessons/pl/01-box-model.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Ustaw padding: 1rem"
+ "message": "Element potrzebuje wewnętrznej przestrzeni — sprawdź właściwość padding"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+steelblue",
- "message": "Ustaw border-left: 4px solid steelblue",
+ "message": "Sprawdź właściwość border-left — jakiej szerokości, stylu i koloru potrzebujesz?",
"options": { "caseSensitive": false }
}
]
@@ -65,7 +65,7 @@
{
"type": "property_value",
"value": { "property": "margin-bottom", "expected": "1rem" },
- "message": "Ustaw margin-bottom: 1rem"
+ "message": "Która właściwość kontroluje przestrzeń pod elementem?"
}
]
},
@@ -86,7 +86,7 @@
{
"type": "property_value",
"value": { "property": "box-sizing", "expected": "border-box" },
- "message": "Ustaw box-sizing: border-box"
+ "message": "Która wartość box-sizing włącza padding i ramkę do szerokości?"
}
]
},
@@ -107,7 +107,7 @@
{
"type": "regex",
"value": "padding:\\s*8px\\s+1rem",
- "message": "Ustaw padding: 8px 1rem",
+ "message": "Sprawdź skrót padding — dwie wartości oznaczają pion i poziom",
"options": { "caseSensitive": false }
}
]
@@ -129,7 +129,7 @@
{
"type": "regex",
"value": "margin:\\s*0\\s+auto",
- "message": "Ustaw margin: 0 auto",
+ "message": "Sprawdź skrót margin — jak automatycznie wycentrować element poziomo?",
"options": { "caseSensitive": false }
}
]
@@ -151,7 +151,7 @@
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "50%" },
- "message": "Ustaw border-radius: 50%"
+ "message": "Która wartość border-radius tworzy pełne koło?"
}
]
},
@@ -172,18 +172,18 @@
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Ustaw padding: 1rem"
+ "message": "Element potrzebuje wewnętrznej przestrzeni — sprawdź właściwość padding"
},
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+coral",
- "message": "Ustaw border-left: 4px solid coral",
+ "message": "Sprawdź właściwość border-left — jaki styl akcentu potrzebuje powiadomienie?",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "4px" },
- "message": "Ustaw border-radius: 4px"
+ "message": "Element potrzebuje zaokrąglonych rogów — sprawdź właściwość border-radius"
}
]
}
diff --git a/lessons/pl/05-units-variables.json b/lessons/pl/05-units-variables.json
index 098c766..a11d437 100644
--- a/lessons/pl/05-units-variables.json
+++ b/lessons/pl/05-units-variables.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "max-width", "expected": "40rem" },
- "message": "Ustaw max-width: 40rem"
+ "message": "Która właściwość ogranicza maksymalną szerokość elementu?"
}
]
},
@@ -49,7 +49,7 @@
{
"type": "contains",
"value": "steelblue",
- "message": "Ustaw wartość na steelblue",
+ "message": "Jaki kolor powinna mieć zmienna brand?",
"options": { "caseSensitive": false }
}
]
@@ -71,7 +71,7 @@
{
"type": "regex",
"value": "width:\\s*calc\\(\\s*100%\\s*-\\s*200px\\s*\\)",
- "message": "Ustaw width: calc(100% - 200px)",
+ "message": "Sprawdź funkcję calc() — jak obliczyć szerokość minus sidebar?",
"options": { "caseSensitive": false }
}
]
@@ -93,7 +93,7 @@
{
"type": "property_value",
"value": { "property": "min-height", "expected": "100vh" },
- "message": "Ustaw min-height: 100vh"
+ "message": "Która właściwość zapewnia minimalną wysokość na cały viewport?"
}
]
}
diff --git a/lessons/pl/06-transitions-animations.json b/lessons/pl/06-transitions-animations.json
index 0d21172..082849d 100644
--- a/lessons/pl/06-transitions-animations.json
+++ b/lessons/pl/06-transitions-animations.json
@@ -28,7 +28,7 @@
{
"type": "regex",
"value": "transition:\\s*background-color\\s*0\\.3s",
- "message": "Ustaw transition: background-color 0.3s",
+ "message": "Sprawdź właściwość transition — jaką właściwość i czas trwania podać?",
"options": { "caseSensitive": false }
}
]
@@ -56,7 +56,7 @@
{
"type": "property_value",
"value": { "property": "transition-timing-function", "expected": "ease-in-out" },
- "message": "Ustaw timing na ease-in-out"
+ "message": "Która wartość tworzy płynne przyspieszenie i spowolnienie?"
}
]
},
@@ -83,7 +83,7 @@
{
"type": "regex",
"value": "50%.*transform: translateY\\(-20px\\)",
- "message": "Przy 50%, użyj transform: translateY(-20px)",
+ "message": "W połowie animacji piłka powinna podskoczyć w górę — sprawdź transform",
"options": { "caseSensitive": false }
},
{
@@ -95,7 +95,7 @@
{
"type": "regex",
"value": "animation:.*bounce.*1s.*infinite",
- "message": "Zastosuj animation: bounce 1s infinite",
+ "message": "Sprawdź skrót animation — podaj nazwę, czas trwania i powtarzanie",
"options": { "caseSensitive": false }
}
]
@@ -117,27 +117,27 @@
{
"type": "property_value",
"value": { "property": "animation-name", "expected": "pulse" },
- "message": "Ustaw animation-name: pulse"
+ "message": "Która właściwość wskazuje nazwę animacji do zastosowania?"
},
{
"type": "property_value",
"value": { "property": "animation-duration", "expected": "2s" },
- "message": "Ustaw animation-duration: 2s"
+ "message": "Sprawdź właściwość animation-duration — jak długo trwa jeden cykl?"
},
{
"type": "property_value",
"value": { "property": "animation-delay", "expected": "1s" },
- "message": "Ustaw animation-delay: 1s"
+ "message": "Sprawdź właściwość animation-delay — ile czeka przed startem?"
},
{
"type": "property_value",
"value": { "property": "animation-iteration-count", "expected": "2" },
- "message": "Ustaw animation-iteration-count: 2"
+ "message": "Sprawdź właściwość animation-iteration-count — ile razy ma się powtórzyć?"
},
{
"type": "property_value",
"value": { "property": "animation-fill-mode", "expected": "forwards" },
- "message": "Ustaw animation-fill-mode: forwards"
+ "message": "Która wartość animation-fill-mode zachowuje końcowy stan animacji?"
}
]
}
diff --git a/lessons/pl/08-responsive.json b/lessons/pl/08-responsive.json
index 273221e..0912a2c 100644
--- a/lessons/pl/08-responsive.json
+++ b/lessons/pl/08-responsive.json
@@ -34,7 +34,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "lightcoral" },
- "message": "Ustaw background: lightcoral",
+ "message": "Sprawdź właściwość background — jaki kolor potrzebuje panel na małych ekranach?",
"options": { "exact": false }
}
]
@@ -53,7 +53,11 @@
"solution": " font-size: 5vw;",
"previewContainer": "preview-area",
"validations": [
- { "type": "property_value", "value": { "property": "font-size", "expected": "5vw" }, "message": "Ustaw font-size: 5vw" }
+ {
+ "type": "property_value",
+ "value": { "property": "font-size", "expected": "5vw" },
+ "message": "Sprawdź właściwość font-size — która jednostka skaluje się z viewport?"
+ }
]
},
{
@@ -73,7 +77,7 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "grid" },
- "message": "Ustaw display: grid"
+ "message": "Która wartość display włącza układ siatkowy?"
},
{
"type": "regex",
@@ -84,7 +88,7 @@
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
- "message": "Ustaw gap: 1rem"
+ "message": "Sprawdź właściwość gap — jaki odstęp potrzebują elementy siatki?"
}
]
},
@@ -117,7 +121,7 @@
{
"type": "property_value",
"value": { "property": "width", "expected": "250px" },
- "message": "Ustaw width: 250px",
+ "message": "Sprawdź właściwość width — jaką stałą szerokość potrzebuje sidebar?",
"options": { "exact": false }
}
]
diff --git a/lessons/pl/flexbox.json b/lessons/pl/flexbox.json
index 5da2f19..53227ef 100644
--- a/lessons/pl/flexbox.json
+++ b/lessons/pl/flexbox.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "flex" },
- "message": "Ustaw display: flex"
+ "message": "Która właściwość display tworzy kontener flex?"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
- "message": "Ustaw gap: 1rem"
+ "message": "Sprawdź właściwość gap — jaki odstęp potrzebują elementy?"
}
]
},
@@ -64,7 +64,7 @@
{
"type": "property_value",
"value": { "property": "justify-content", "expected": "space-between" },
- "message": "Ustaw justify-content: space-between"
+ "message": "Która wartość justify-content rozdziela elementy na końce?"
}
]
},
@@ -85,7 +85,7 @@
{
"type": "property_value",
"value": { "property": "align-items", "expected": "center" },
- "message": "Ustaw align-items: center"
+ "message": "Która właściwość kontroluje wyrównanie na osi poprzecznej?"
}
]
},
@@ -106,7 +106,7 @@
{
"type": "property_value",
"value": { "property": "flex-wrap", "expected": "wrap" },
- "message": "Ustaw flex-wrap: wrap"
+ "message": "Sprawdź właściwość flex-wrap — jak pozwolić elementom przenosić się na nowe linie?"
}
]
},
@@ -127,7 +127,7 @@
{
"type": "property_value",
"value": { "property": "flex", "expected": "1" },
- "message": "Ustaw flex: 1"
+ "message": "Sprawdź właściwość flex — jak sprawić, by element wypełnił dostępną przestrzeń?"
}
]
}
diff --git a/lessons/uk/00-basic-selectors.json b/lessons/uk/00-basic-selectors.json
index 75b981e..0ace717 100644
--- a/lessons/uk/00-basic-selectors.json
+++ b/lessons/uk/00-basic-selectors.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
- "message": "Додайте color: coral;"
+ "message": "Яка властивість керує кольором тексту?"
}
]
},
@@ -43,12 +43,12 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "lavender" },
- "message": "Додайте background: lavender;"
+ "message": "Перевірте властивість background"
},
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Додайте padding: 1rem;"
+ "message": "Картка потребує простору всередині її меж"
}
]
},
@@ -74,7 +74,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "steelblue" },
- "message": "Встановіть color: steelblue"
+ "message": "Яка властивість змінює колір тексту?"
}
]
},
@@ -100,7 +100,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
- "message": "Встановіть color: coral"
+ "message": "Яке значення дає теплий червонувато-оранжевий колір?"
}
]
},
@@ -126,7 +126,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "tomato" },
- "message": "Встановіть background: tomato"
+ "message": "Значку потрібен яскравий червоний фон"
}
]
},
@@ -152,7 +152,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "steelblue" },
- "message": "Встановіть background: steelblue"
+ "message": "Яка властивість встановлює колір заливки кнопки?"
}
]
},
@@ -178,7 +178,7 @@
{
"type": "property_value",
"value": { "property": "text-decoration", "expected": "none" },
- "message": "Встановіть text-decoration: none"
+ "message": "Яка властивість керує підкресленням посилань?"
}
]
},
@@ -199,7 +199,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "steelblue" },
- "message": "Встановіть color: steelblue"
+ "message": "Перевірте властивість color"
}
]
},
@@ -225,7 +225,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "white" },
- "message": "Встановіть color: white"
+ "message": "Посилання мають виділятися на синьому фоні"
}
]
},
@@ -251,7 +251,7 @@
{
"type": "property_value",
"value": { "property": "font-size", "expected": "0.9rem" },
- "message": "Встановіть font-size: 0.9rem"
+ "message": "Перевірте властивість font-size — текст має бути трохи меншим"
}
]
}
diff --git a/lessons/uk/01-box-model.json b/lessons/uk/01-box-model.json
index 8478ba0..ae96423 100644
--- a/lessons/uk/01-box-model.json
+++ b/lessons/uk/01-box-model.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Встановіть padding: 1rem"
+ "message": "Яка властивість додає простір між вмістом елемента та його межею?"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+steelblue",
- "message": "Встановіть border-left: 4px solid steelblue",
+ "message": "Використайте скорочення border-left зі значеннями ширини, стилю та кольору",
"options": { "caseSensitive": false }
}
]
@@ -65,7 +65,7 @@
{
"type": "property_value",
"value": { "property": "margin-bottom", "expected": "1rem" },
- "message": "Встановіть margin-bottom: 1rem"
+ "message": "Яка властивість створює простір знизу елемента, відштовхуючи сусідів?"
}
]
},
@@ -86,7 +86,7 @@
{
"type": "property_value",
"value": { "property": "box-sizing", "expected": "border-box" },
- "message": "Встановіть box-sizing: border-box"
+ "message": "Яке значення box-sizing включає padding та межу в загальну ширину елемента?"
}
]
},
@@ -107,7 +107,7 @@
{
"type": "regex",
"value": "padding:\\s*8px\\s+1rem",
- "message": "Встановіть padding: 8px 1rem",
+ "message": "Використайте скорочення padding з двома значеннями: вертикальне та горизонтальне",
"options": { "caseSensitive": false }
}
]
@@ -129,7 +129,7 @@
{
"type": "regex",
"value": "margin:\\s*0\\s+auto",
- "message": "Встановіть margin: 0 auto",
+ "message": "Використайте margin з ключовим словом, яке автоматично обчислює рівні ліві та праві відступи",
"options": { "caseSensitive": false }
}
]
@@ -151,7 +151,7 @@
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "50%" },
- "message": "Встановіть border-radius: 50%"
+ "message": "Який відсоток border-radius створює ідеальне коло з квадратного елемента?"
}
]
},
@@ -172,18 +172,18 @@
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
- "message": "Встановіть padding: 1rem"
+ "message": "Додайте внутрішній відступ до картки сповіщення"
},
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+coral",
- "message": "Встановіть border-left: 4px solid coral",
+ "message": "Додайте лівий акцент за допомогою скорочення border-left",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "4px" },
- "message": "Встановіть border-radius: 4px"
+ "message": "Злегка заокругліть кути за допомогою border-radius"
}
]
}
diff --git a/lessons/uk/05-units-variables.json b/lessons/uk/05-units-variables.json
index da86551..2207224 100644
--- a/lessons/uk/05-units-variables.json
+++ b/lessons/uk/05-units-variables.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "max-width", "expected": "40rem" },
- "message": "Встановіть max-width: 40rem"
+ "message": "Яка властивість обмежує ширину елемента? Спробуйте значення в rem для комфортної довжини рядка."
}
]
},
@@ -49,7 +49,7 @@
{
"type": "contains",
"value": "steelblue",
- "message": "Встановіть значення steelblue",
+ "message": "Встановіть значення на steelblue",
"options": { "caseSensitive": false }
}
]
@@ -71,7 +71,7 @@
{
"type": "regex",
"value": "width:\\s*calc\\(\\s*100%\\s*-\\s*200px\\s*\\)",
- "message": "Встановіть width: calc(100% - 200px)",
+ "message": "Використайте calc(), щоб відняти фіксовану ширину сайдбару від повної ширини контейнера.",
"options": { "caseSensitive": false }
}
]
@@ -93,7 +93,7 @@
{
"type": "property_value",
"value": { "property": "min-height", "expected": "100vh" },
- "message": "Встановіть min-height: 100vh"
+ "message": "Яка властивість забезпечує мінімальну висоту? Використайте одиницю viewport для повноекранного покриття."
}
]
}
diff --git a/lessons/uk/06-transitions-animations.json b/lessons/uk/06-transitions-animations.json
index 1066fdc..efa9968 100644
--- a/lessons/uk/06-transitions-animations.json
+++ b/lessons/uk/06-transitions-animations.json
@@ -28,7 +28,7 @@
{
"type": "regex",
"value": "transition:\\s*background-color\\s*0\\.3s",
- "message": "Встановіть transition: background-color 0.3s",
+ "message": "Вкажіть, яку властивість анімувати та скільки це має тривати.",
"options": { "caseSensitive": false }
}
]
@@ -56,7 +56,7 @@
{
"type": "property_value",
"value": { "property": "transition-timing-function", "expected": "ease-in-out" },
- "message": "Встановіть timing на ease-in-out"
+ "message": "Яке ключове слово пом'якшення починається повільно, прискорюється, а потім знову сповільнюється?"
}
]
},
@@ -95,7 +95,7 @@
{
"type": "regex",
"value": "animation:.*bounce.*1s.*infinite",
- "message": "Застосуйте animation: bounce 1s infinite",
+ "message": "Використайте скорочення animation: назва, тривалість та кількість повторень.",
"options": { "caseSensitive": false }
}
]
@@ -117,27 +117,27 @@
{
"type": "property_value",
"value": { "property": "animation-name", "expected": "pulse" },
- "message": "Встановіть animation-name: pulse"
+ "message": "Яка властивість пов'язує елемент з іменованим правилом @keyframes?"
},
{
"type": "property_value",
"value": { "property": "animation-duration", "expected": "2s" },
- "message": "Встановіть animation-duration: 2s"
+ "message": "Скільки має тривати один повний цикл анімації?"
},
{
"type": "property_value",
"value": { "property": "animation-delay", "expected": "1s" },
- "message": "Встановіть animation-delay: 1s"
+ "message": "Яка властивість змушує анімацію зачекати перед початком?"
},
{
"type": "property_value",
"value": { "property": "animation-iteration-count", "expected": "2" },
- "message": "Встановіть animation-iteration-count: 2"
+ "message": "Яка властивість контролює кількість повторень анімації?"
},
{
"type": "property_value",
"value": { "property": "animation-fill-mode", "expected": "forwards" },
- "message": "Встановіть animation-fill-mode: forwards"
+ "message": "Яка властивість зберігає стиль елемента в його фінальному стані keyframe після завершення анімації?"
}
]
}
diff --git a/lessons/uk/08-responsive.json b/lessons/uk/08-responsive.json
index a432f73..e7221b4 100644
--- a/lessons/uk/08-responsive.json
+++ b/lessons/uk/08-responsive.json
@@ -22,7 +22,7 @@
{
"type": "regex",
"value": "@media\\s*\\(max-width:\\s*600px\\)",
- "message": "Використайте @media (max-width: 600px)",
+ "message": "Почніть з правила @media — яка умова націлюється на екрани шириною 600px або менше?",
"options": { "caseSensitive": false }
},
{
@@ -34,7 +34,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "lightcoral" },
- "message": "Встановіть background: lightcoral",
+ "message": "Яка властивість змінює колір фону елемента?",
"options": { "exact": false }
}
]
@@ -56,7 +56,7 @@
{
"type": "property_value",
"value": { "property": "font-size", "expected": "5vw" },
- "message": "Встановіть font-size: 5vw"
+ "message": "Яка одиниця CSS масштабується відносно ширини viewport?"
}
]
},
@@ -77,18 +77,18 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "grid" },
- "message": "Встановіть display: grid"
+ "message": "Який режим display дозволяє визначати рядки та колонки?"
},
{
"type": "regex",
"value": "repeat\\(auto-fit,\\s*minmax\\(200px,\\s*1fr\\)\\)",
- "message": "Використайте repeat(auto-fit, minmax(200px, 1fr))",
+ "message": "Спробуйте repeat() з auto-fit та minmax() — які мінімальний та максимальний розміри створять гнучкі колонки?",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
- "message": "Встановіть gap: 1rem"
+ "message": "Яка властивість додає простір між елементами grid?"
}
]
},
@@ -109,7 +109,7 @@
{
"type": "regex",
"value": "@media\\s*\\(min-width:\\s*768px\\)",
- "message": "Використайте @media (min-width: 768px)",
+ "message": "Яка умова @media застосовує стилі, коли viewport має ширину щонайменше 768px?",
"options": { "caseSensitive": false }
},
{
@@ -121,7 +121,7 @@
{
"type": "property_value",
"value": { "property": "width", "expected": "250px" },
- "message": "Встановіть width: 250px",
+ "message": "Яка властивість контролює ширину сайдбару на великих екранах?",
"options": { "exact": false }
}
]
diff --git a/lessons/uk/flexbox.json b/lessons/uk/flexbox.json
index ce48da9..bbe6592 100644
--- a/lessons/uk/flexbox.json
+++ b/lessons/uk/flexbox.json
@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "flex" },
- "message": "Встановіть display: flex"
+ "message": "Яке значення display перетворює елемент на гнучкий контейнер?"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
- "message": "Встановіть gap: 1rem"
+ "message": "Яка властивість створює відстань між flex-елементами без використання margin?"
}
]
},
@@ -64,7 +64,7 @@
{
"type": "property_value",
"value": { "property": "justify-content", "expected": "space-between" },
- "message": "Встановіть justify-content: space-between"
+ "message": "Яке значення justify-content розміщує перший та останній елементи на протилежних краях?"
}
]
},
@@ -85,7 +85,7 @@
{
"type": "property_value",
"value": { "property": "align-items", "expected": "center" },
- "message": "Встановіть align-items: center"
+ "message": "Яка властивість вирівнює flex-елементи вздовж поперечної осі?"
}
]
},
@@ -106,7 +106,7 @@
{
"type": "property_value",
"value": { "property": "flex-wrap", "expected": "wrap" },
- "message": "Встановіть flex-wrap: wrap"
+ "message": "Яка властивість дозволяє flex-елементам переходити на кілька рядків?"
}
]
},
@@ -127,7 +127,7 @@
{
"type": "property_value",
"value": { "property": "flex", "expected": "1" },
- "message": "Встановіть flex: 1"
+ "message": "Яка властивість змушує flex-елемент зростати, щоб заповнити залишковий простір?"
}
]
}
diff --git a/specs/004-pedagogical-messages/tasks.md b/specs/004-pedagogical-messages/tasks.md
index 60f285b..1ce5421 100644
--- a/specs/004-pedagogical-messages/tasks.md
+++ b/specs/004-pedagogical-messages/tasks.md
@@ -1,39 +1,39 @@
# Tasks
## Phase 1: Preparation
-- [ ] Task 1.1: Audit existing tests for hardcoded validation message assertions; note any that need updating
-- [ ] Task 1.2: Read each priority English module and draft replacement messages using the hint style guide (concept question / property hint / directional nudge)
+- [X] Task 1.1: Audit existing tests for hardcoded validation message assertions; note any that need updating
+- [X] Task 1.2: Read each priority English module and draft replacement messages using the hint style guide (concept question / property hint / directional nudge)
## Phase 2: English Priority Modules (100% answer-revealing)
-- [ ] Task 2.1: Rewrite validation messages in `lessons/flexbox.json` (6 messages) [P]
-- [ ] Task 2.2: Rewrite validation messages in `lessons/01-box-model.json` (10 messages) [P]
-- [ ] Task 2.3: Rewrite validation messages in `lessons/03-colors.json` (4 messages) [P]
-- [ ] Task 2.4: Rewrite validation messages in `lessons/12-positioning.json` (5 messages) [P]
+- [X] Task 2.1: Rewrite validation messages in `lessons/flexbox.json` (6 messages) [P]
+- [X] Task 2.2: Rewrite validation messages in `lessons/01-box-model.json` (10 messages) [P]
+- [X] Task 2.3: Rewrite validation messages in `lessons/03-colors.json` (4 messages) [P]
+- [X] Task 2.4: Rewrite validation messages in `lessons/12-positioning.json` (5 messages) [P]
## Phase 3: English Remaining Modules
-- [ ] Task 3.1: Rewrite messages in `lessons/00-basic-selectors.json` (15 messages) [P]
-- [ ] Task 3.2: Rewrite messages in `lessons/00-basics.json` (4 messages) [P]
-- [ ] Task 3.3: Rewrite messages in `lessons/01-advanced-selectors.json` (8 messages) [P]
-- [ ] Task 3.4: Rewrite messages in `lessons/04-typography.json` (1 message) [P]
-- [ ] Task 3.5: Rewrite messages in `lessons/05-units-variables.json` (3 messages) [P]
-- [ ] Task 3.6: Rewrite messages in `lessons/06-transitions-animations.json` (8 messages) [P]
-- [ ] Task 3.7: Rewrite messages in `lessons/07-layouts.json` (8 messages) [P]
-- [ ] Task 3.8: Rewrite messages in `lessons/08-responsive.json` (8 messages) [P]
-- [ ] Task 3.9: Rewrite messages in `lessons/09-gradients.json` (3 messages) [P]
-- [ ] Task 3.10: Rewrite messages in `lessons/10-tailwind-basics.json` (16 messages) [P]
-- [ ] Task 3.11: Rewrite messages in `lessons/11-filters.json` (4 messages) [P]
-- [ ] Task 3.12: Rewrite messages in `lessons/13-pseudo-elements.json` (4 messages) [P]
-- [ ] Task 3.13: Rewrite messages in `lessons/grid.json` (5 messages) [P]
+- [X] Task 3.1: Rewrite messages in `lessons/00-basic-selectors.json` (15 messages) [P]
+- [X] Task 3.2: Rewrite messages in `lessons/00-basics.json` (4 messages) [P]
+- [X] Task 3.3: Rewrite messages in `lessons/01-advanced-selectors.json` (8 messages) [P]
+- [X] Task 3.4: Rewrite messages in `lessons/04-typography.json` (1 message) [P]
+- [X] Task 3.5: Rewrite messages in `lessons/05-units-variables.json` (3 messages) [P]
+- [X] Task 3.6: Rewrite messages in `lessons/06-transitions-animations.json` (8 messages) [P]
+- [X] Task 3.7: Rewrite messages in `lessons/07-layouts.json` (8 messages) [P]
+- [X] Task 3.8: Rewrite messages in `lessons/08-responsive.json` (8 messages) [P]
+- [X] Task 3.9: Rewrite messages in `lessons/09-gradients.json` (3 messages) [P]
+- [X] Task 3.10: Rewrite messages in `lessons/10-tailwind-basics.json` (16 messages) [P]
+- [X] Task 3.11: Rewrite messages in `lessons/11-filters.json` (4 messages) [P]
+- [X] Task 3.12: Rewrite messages in `lessons/13-pseudo-elements.json` (4 messages) [P]
+- [X] Task 3.13: Rewrite messages in `lessons/grid.json` (5 messages) [P]
## Phase 4: Localized Variants
-- [ ] Task 4.1: Update Arabic (ar/) localized modules with pedagogical messages [P]
-- [ ] Task 4.2: Update German (de/) localized modules with pedagogical messages [P]
-- [ ] Task 4.3: Update Spanish (es/) localized modules with pedagogical messages [P]
-- [ ] Task 4.4: Update Polish (pl/) localized modules with pedagogical messages [P]
-- [ ] Task 4.5: Update Ukrainian (uk/) localized modules with pedagogical messages [P]
+- [X] Task 4.1: Update Arabic (ar/) localized modules with pedagogical messages [P]
+- [X] Task 4.2: Update German (de/) localized modules with pedagogical messages [P]
+- [X] Task 4.3: Update Spanish (es/) localized modules with pedagogical messages [P]
+- [X] Task 4.4: Update Polish (pl/) localized modules with pedagogical messages [P]
+- [X] Task 4.5: Update Ukrainian (uk/) localized modules with pedagogical messages [P]
## Phase 5: Validation & Polish
-- [ ] Task 5.1: Run `npm run format.lessons` to ensure JSON formatting consistency
-- [ ] Task 5.2: Run `npm run test` and fix any test failures related to message text assertions
-- [ ] Task 5.3: Grep audit — verify no "Set " answer-revealing patterns remain in any lesson file
-- [ ] Task 5.4: Spot-check a few lessons via `npm start` to confirm messages render correctly in the UI
+- [X] Task 5.1: Run `npm run format.lessons` to ensure JSON formatting consistency
+- [X] Task 5.2: Run `npm run test` and fix any test failures related to message text assertions
+- [X] Task 5.3: Grep audit — verify no "Set " answer-revealing patterns remain in any lesson file
+- [X] Task 5.4: Spot-check a few lessons via `npm start` to confirm messages render correctly in the UI