Compare commits
2 Commits
main
...
004-pedago
| Author | SHA1 | Date | |
|---|---|---|---|
| c560676544 | |||
| 782e87705c |
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "coral" },
|
||||
"message": "Add <kbd>color: coral;</kbd>"
|
||||
"message": "Which property controls text color?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -43,12 +43,12 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "lavender" },
|
||||
"message": "Add <kbd>background: lavender;</kbd>"
|
||||
"message": "Check the <kbd>background</kbd> property"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "Add <kbd>padding: 1rem;</kbd>"
|
||||
"message": "The card needs space inside its edges"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -74,7 +74,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "steelblue" },
|
||||
"message": "Set <kbd>color: steelblue</kbd>"
|
||||
"message": "Which property changes text color?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -100,7 +100,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "coral" },
|
||||
"message": "Set <kbd>color: coral</kbd>"
|
||||
"message": "What value gives a warm, reddish-orange color?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -126,7 +126,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "tomato" },
|
||||
"message": "Set <kbd>background: tomato</kbd>"
|
||||
"message": "The badge needs a bright red background"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -152,7 +152,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "steelblue" },
|
||||
"message": "Set <kbd>background: steelblue</kbd>"
|
||||
"message": "Which property sets the button's fill color?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -178,7 +178,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "text-decoration", "expected": "none" },
|
||||
"message": "Set <kbd>text-decoration: none</kbd>"
|
||||
"message": "Which property controls the underline on links?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -199,7 +199,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "steelblue" },
|
||||
"message": "Set <kbd>color: steelblue</kbd>"
|
||||
"message": "Check the <kbd>color</kbd> property"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -225,7 +225,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "white" },
|
||||
"message": "Set <kbd>color: white</kbd>"
|
||||
"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 <kbd>font-size: 0.9rem</kbd>"
|
||||
"message": "Check the <kbd>font-size</kbd> property — the text should be slightly smaller"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
"property": "padding",
|
||||
"expected": "20px"
|
||||
},
|
||||
"message": "Set the padding value to <kbd>20px</kbd>",
|
||||
"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 <kbd>30px</kbd>",
|
||||
"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 <kbd>2px solid blue</kbd>",
|
||||
"message": "The <kbd>border</kbd> shorthand takes three parts: width, style, and color",
|
||||
"options": {
|
||||
"caseSensitive": false
|
||||
}
|
||||
@@ -246,7 +246,7 @@
|
||||
"property": "justify-content",
|
||||
"expected": "center"
|
||||
},
|
||||
"message": "Set <kbd>justify-content</kbd> to <kbd>center</kbd>",
|
||||
"message": "How do you center items along the main axis?",
|
||||
"options": {
|
||||
"exact": true
|
||||
}
|
||||
@@ -265,7 +265,7 @@
|
||||
"property": "align-items",
|
||||
"expected": "center"
|
||||
},
|
||||
"message": "Set <kbd>align-items</kbd> to <kbd>center</kbd>",
|
||||
"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 <kbd>Courier, monospace</kbd>",
|
||||
"message": "A font stack lists preferred fonts first, followed by a generic fallback, separated by commas",
|
||||
"options": {
|
||||
"caseSensitive": false
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "^input\\[type=\"text\"\\]\\s*{",
|
||||
"message": "Use <kbd>input[type=\"text\"] { … }</kbd> 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 <kbd>a[href^=\"https\"] { … }</kbd> as your attribute selector to target HTTPS links",
|
||||
"message": "Which partial-match attribute selector targets values that <em>start with</em> 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 <kbd>.main-nav > li { … }</kbd> with the child combinator to target only direct children",
|
||||
"message": "Which combinator selects only <em>direct</em> 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 <kbd>nav a</kbd> 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 <kbd>h2 + p</kbd> with the adjacent sibling combinator (+)",
|
||||
"message": "Which combinator targets the element <em>immediately</em> 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 <kbd>h3 ~ p</kbd> with the general sibling combinator (~)",
|
||||
"message": "Which combinator selects <em>all</em> 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 <kbd>button:hover</kbd> 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 <kbd>li:first-child</kbd> to target first list items",
|
||||
"message": "Which pseudo-class selects an element only when it is the <em>first</em> child of its parent? Attach it to the <kbd>li</kbd> selector.",
|
||||
"options": {
|
||||
"caseSensitive": true
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "Set <kbd>padding: 1rem</kbd>"
|
||||
"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 <kbd>border-left: 4px solid steelblue</kbd>",
|
||||
"message": "Use the <kbd>border-left</kbd> 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 <kbd>margin-bottom: 1rem</kbd>"
|
||||
"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 <kbd>box-sizing: border-box</kbd>"
|
||||
"message": "Which <kbd>box-sizing</kbd> 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 <kbd>padding: 8px 1rem</kbd>",
|
||||
"message": "Use the <kbd>padding</kbd> shorthand with two values: vertical then horizontal",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -129,7 +129,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "margin:\\s*0\\s+auto",
|
||||
"message": "Set <kbd>margin: 0 auto</kbd>",
|
||||
"message": "Use <kbd>margin</kbd> 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 <kbd>border-radius: 50%</kbd>"
|
||||
"message": "Which <kbd>border-radius</kbd> percentage creates a perfect circle from a square element?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -172,18 +172,18 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "Set <kbd>padding: 1rem</kbd>"
|
||||
"message": "Add inner spacing to the notification card"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "border-left:\\s*4px\\s+solid\\s+coral",
|
||||
"message": "Set <kbd>border-left: 4px solid coral</kbd>",
|
||||
"message": "Add a left border accent using the <kbd>border-left</kbd> shorthand",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "border-radius", "expected": "4px" },
|
||||
"message": "Set <kbd>border-radius: 4px</kbd>"
|
||||
"message": "Round the corners slightly with <kbd>border-radius</kbd>"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background-color", "expected": "seashell" },
|
||||
"message": "Set <kbd>background-color: seashell</kbd>"
|
||||
"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 <kbd>color: coral</kbd>"
|
||||
"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 <kbd>border-color: coral</kbd>"
|
||||
"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 <kbd>background-color: #ffd700</kbd>"
|
||||
"message": "Set the <kbd>background-color</kbd> using a hex code format"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
{
|
||||
"type": "contains",
|
||||
"value": "2px 2px",
|
||||
"message": "Set offset to <kbd>2px 2px</kbd>"
|
||||
"message": "How far should the shadow move horizontally and vertically?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "max-width", "expected": "40rem" },
|
||||
"message": "Set <kbd>max-width: 40rem</kbd>"
|
||||
"message": "Which property caps an element's width? Try a <kbd>rem</kbd> value for readable line length."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -71,7 +71,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "width:\\s*calc\\(\\s*100%\\s*-\\s*200px\\s*\\)",
|
||||
"message": "Set <kbd>width: calc(100% - 200px)</kbd>",
|
||||
"message": "Use <kbd>calc()</kbd> 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 <kbd>min-height: 100vh</kbd>"
|
||||
"message": "Which property ensures a minimum height? Use a viewport unit for full-screen coverage."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "transition:\\s*background-color\\s*0\\.3s",
|
||||
"message": "Set <kbd>transition: background-color 0.3s</kbd>",
|
||||
"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 <kbd>ease-in-out</kbd>"
|
||||
"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 <kbd>animation: bounce 1s infinite</kbd>",
|
||||
"message": "Use the <kbd>animation</kbd> shorthand: name, duration, and repeat count.",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -117,27 +117,27 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-name", "expected": "pulse" },
|
||||
"message": "Set <kbd>animation-name: pulse</kbd>"
|
||||
"message": "Which property links an element to a named <kbd>@keyframes</kbd> rule?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-duration", "expected": "2s" },
|
||||
"message": "Set <kbd>animation-duration: 2s</kbd>"
|
||||
"message": "How long should one full cycle of the animation take?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-delay", "expected": "1s" },
|
||||
"message": "Set <kbd>animation-delay: 1s</kbd>"
|
||||
"message": "Which property makes the animation wait before starting?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-iteration-count", "expected": "2" },
|
||||
"message": "Set <kbd>animation-iteration-count: 2</kbd>"
|
||||
"message": "Which property controls how many times the animation repeats?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-fill-mode", "expected": "forwards" },
|
||||
"message": "Set <kbd>animation-fill-mode: forwards</kbd>"
|
||||
"message": "Which property keeps the element styled in its final keyframe state after the animation ends?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -18,14 +18,24 @@
|
||||
"codeSuffix": "}",
|
||||
"previewContainer": "preview-area",
|
||||
"validations": [
|
||||
{ "type": "contains", "value": "display", "message": "Use <kbd>display: flex</kbd>", "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 <kbd>justify-content: center</kbd>",
|
||||
"message": "How do you center items along the main axis?",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{ "type": "contains", "value": "align-items", "message": "Use <kbd>align-items: center</kbd>", "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 <kbd>flex-wrap: wrap</kbd>",
|
||||
"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 <kbd>flex: 1 1 100px</kbd> on items",
|
||||
"message": "The <kbd>flex</kbd> 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 <kbd>display: grid</kbd>", "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 <kbd>grid-template-columns</kbd>",
|
||||
"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 <kbd>repeat(3, 1fr)</kbd>",
|
||||
"message": "The <kbd>repeat()</kbd> 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 <kbd>gap</kbd> 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 <kbd>grid-column: 1 / span 2</kbd>",
|
||||
"message": "Use <kbd>grid-column</kbd> with a start line and a span count \u2014 how many columns should this item stretch across?",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "@media\\s*\\(max-width:\\s*600px\\)",
|
||||
"message": "Use <kbd>@media (max-width: 600px)</kbd>",
|
||||
"message": "Start with an <kbd>@media</kbd> 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 <kbd>background: lightcoral</kbd>",
|
||||
"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 <kbd>font-size: 5vw</kbd>" }
|
||||
{
|
||||
"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 <kbd>display: grid</kbd>"
|
||||
"message": "Which display mode lets you define rows and columns?"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "repeat\\(auto-fit,\\s*minmax\\(200px,\\s*1fr\\)\\)",
|
||||
"message": "Use <kbd>repeat(auto-fit, minmax(200px, 1fr))</kbd>",
|
||||
"message": "Try <kbd>repeat()</kbd> with <kbd>auto-fit</kbd> and <kbd>minmax()</kbd> — what minimum and maximum sizes create flexible columns?",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "gap", "expected": "1rem" },
|
||||
"message": "Set <kbd>gap: 1rem</kbd>"
|
||||
"message": "Which property adds space between grid items?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -105,7 +109,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "@media\\s*\\(min-width:\\s*768px\\)",
|
||||
"message": "Use <kbd>@media (min-width: 768px)</kbd>",
|
||||
"message": "Which <kbd>@media</kbd> 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 <kbd>width: 250px</kbd>",
|
||||
"message": "Which property controls how wide the sidebar should be on larger screens?",
|
||||
"options": { "exact": false }
|
||||
}
|
||||
]
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "contains",
|
||||
"value": "linear-gradient",
|
||||
"message": "Use <kbd>linear-gradient()</kbd>"
|
||||
"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 <kbd>to right</kbd> 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 <kbd>radial-gradient()</kbd>"
|
||||
"message": "Which CSS function creates a gradient that radiates outward from a center point?"
|
||||
},
|
||||
{
|
||||
"type": "contains",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "bg-blue-500",
|
||||
"message": "Add the <kbd>bg-blue-500</kbd> class for a blue background."
|
||||
"message": "Which Tailwind utility sets a blue background color? Think about the <kbd>bg-{color}-{shade}</kbd> pattern."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -38,22 +38,22 @@
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "bg-white",
|
||||
"message": "Add <kbd>bg-white</kbd> to set the background color to white."
|
||||
"message": "Which Tailwind utility sets a white background? The pattern is <kbd>bg-{color}</kbd>."
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "p-4",
|
||||
"message": "Add <kbd>p-4</kbd> 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 <kbd>rounded</kbd> 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 <kbd>shadow-sm</kbd> to apply small drop-shadow."
|
||||
"message": "Which Tailwind utility adds a small drop-shadow? Look for a <kbd>shadow-</kbd> variant."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -71,17 +71,17 @@
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "text-blue-600",
|
||||
"message": "Add <kbd>text-blue-600</kbd> to make the text blue"
|
||||
"message": "Which Tailwind utility controls text color? Use the <kbd>text-{color}-{shade}</kbd> pattern with a blue shade."
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "text-2xl",
|
||||
"message": "Add <kbd>text-2xl</kbd> to increase the font size to 1.5rem"
|
||||
"message": "Which Tailwind utility sets the font size to 1.5rem? Check the <kbd>text-{size}</kbd> scale."
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "font-bold",
|
||||
"message": "Add <kbd>font-bold</kbd> to make the text bold (font-weight: 700)"
|
||||
"message": "Which Tailwind utility makes text bold? The <kbd>font-{weight}</kbd> pattern controls font weight."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -99,17 +99,17 @@
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "px-6",
|
||||
"message": "Add <kbd>px-6</kbd> for horizontal padding (1.5rem left and right)"
|
||||
"message": "Which Tailwind utility adds horizontal padding of 1.5rem? The <kbd>px-</kbd> prefix targets left and right."
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "py-3",
|
||||
"message": "Add <kbd>py-3</kbd> for vertical padding (0.75rem top and bottom)"
|
||||
"message": "Which Tailwind utility adds vertical padding of 0.75rem? The <kbd>py-</kbd> prefix targets top and bottom."
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "mx-auto",
|
||||
"message": "Add <kbd>mx-auto</kbd> 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 <kbd>w-full</kbd> 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 <kbd>md:w-1/2</kbd> for 50% width on tablet and up"
|
||||
"message": "How do you set 50% width at the <kbd>md:</kbd> breakpoint? Tailwind uses fraction notation for widths."
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "lg:w-1/3",
|
||||
"message": "Add <kbd>lg:w-1/3</kbd> for 33.33% width on desktop and up"
|
||||
"message": "How do you set one-third width at the <kbd>lg:</kbd> breakpoint? Use the same fraction pattern."
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "text-lg",
|
||||
"message": "Add <kbd>text-lg</kbd> for the base text size"
|
||||
"message": "Which Tailwind text size utility is one step above the base size? Think about the <kbd>text-{size}</kbd> scale."
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "md:text-xl",
|
||||
"message": "Add <kbd>md:text-xl</kbd> for larger text on tablets"
|
||||
"message": "How do you increase the text size at the <kbd>md:</kbd> breakpoint? Go one step larger."
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "lg:text-2xl",
|
||||
"message": "Add <kbd>lg:text-2xl</kbd> for even larger text on desktop"
|
||||
"message": "How do you set an even larger text size at the <kbd>lg:</kbd> breakpoint? Continue stepping up the scale."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "filter", "expected": "blur(4px)" },
|
||||
"message": "Set <kbd>filter: blur(4px)</kbd>"
|
||||
"message": "Which CSS property applies visual effects like blur? Use the <kbd>blur()</kbd> function with a pixel value."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -48,7 +48,7 @@
|
||||
{
|
||||
"type": "contains",
|
||||
"value": "100%",
|
||||
"message": "Set to <kbd>100%</kbd> for full grayscale"
|
||||
"message": "What percentage value removes all color completely?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -74,7 +74,7 @@
|
||||
{
|
||||
"type": "contains",
|
||||
"value": "120%",
|
||||
"message": "Set to <kbd>120%</kbd>"
|
||||
"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."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "position", "expected": "relative" },
|
||||
"message": "Set <kbd>position: relative</kbd>"
|
||||
"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 <kbd>top: -8px</kbd>"
|
||||
"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 <kbd>position: absolute</kbd>"
|
||||
"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 <kbd>top: 8px</kbd>"
|
||||
"message": "Which offset property controls the distance from the top of the positioned ancestor?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "right", "expected": "8px" },
|
||||
"message": "Set <kbd>right: 8px</kbd>"
|
||||
"message": "Which offset property controls the distance from the right edge?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "coral" },
|
||||
"message": "Set <kbd>color: coral</kbd>"
|
||||
"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 <kbd>width: 40px</kbd>"
|
||||
"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 <kbd>height: 3px</kbd>"
|
||||
"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 <kbd>background: steelblue</kbd>"
|
||||
"message": "Which CSS property fills the line with color? Use a steel-toned blue named color."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "coral" },
|
||||
"message": "أضف <kbd>color: coral;</kbd>"
|
||||
"message": "ما الخاصية التي تتحكم في لون النص؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -43,12 +43,12 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "lavender" },
|
||||
"message": "أضف <kbd>background: lavender;</kbd>"
|
||||
"message": "تحقق من خاصية <kbd>background</kbd>"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "أضف <kbd>padding: 1rem;</kbd>"
|
||||
"message": "البطاقة تحتاج إلى مساحة داخل حوافها"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -74,7 +74,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "steelblue" },
|
||||
"message": "اضبط <kbd>color: steelblue</kbd>"
|
||||
"message": "ما الخاصية التي تغيّر لون النص؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -100,7 +100,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "coral" },
|
||||
"message": "اضبط <kbd>color: coral</kbd>"
|
||||
"message": "ما القيمة التي تعطي لوناً دافئاً برتقالياً محمراً؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -126,7 +126,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "tomato" },
|
||||
"message": "اضبط <kbd>background: tomato</kbd>"
|
||||
"message": "الشارة تحتاج إلى خلفية حمراء زاهية"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -152,7 +152,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "steelblue" },
|
||||
"message": "اضبط <kbd>background: steelblue</kbd>"
|
||||
"message": "ما الخاصية التي تضبط لون تعبئة الزر؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -178,7 +178,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "text-decoration", "expected": "none" },
|
||||
"message": "اضبط <kbd>text-decoration: none</kbd>"
|
||||
"message": "ما الخاصية التي تتحكم في الخط أسفل الروابط؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -199,7 +199,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "steelblue" },
|
||||
"message": "اضبط <kbd>color: steelblue</kbd>"
|
||||
"message": "تحقق من خاصية <kbd>color</kbd>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -225,7 +225,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "white" },
|
||||
"message": "اضبط <kbd>color: white</kbd>"
|
||||
"message": "الروابط تحتاج إلى أن تبرز على الخلفية الزرقاء"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -251,7 +251,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "font-size", "expected": "0.9rem" },
|
||||
"message": "اضبط <kbd>font-size: 0.9rem</kbd>"
|
||||
"message": "تحقق من خاصية <kbd>font-size</kbd> — النص يجب أن يكون أصغر قليلاً"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "اضبط <kbd>padding: 1rem</kbd>"
|
||||
"message": "ما الخاصية التي تضيف مساحة بين محتوى العنصر وحدوده؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -43,7 +43,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "border-left:\\s*4px\\s+solid\\s+steelblue",
|
||||
"message": "اضبط <kbd>border-left: 4px solid steelblue</kbd>",
|
||||
"message": "استخدم اختصار <kbd>border-left</kbd> مع قيم العرض والنمط واللون",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -65,7 +65,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "margin-bottom", "expected": "1rem" },
|
||||
"message": "اضبط <kbd>margin-bottom: 1rem</kbd>"
|
||||
"message": "ما الخاصية التي تُنشئ مساحة أسفل العنصر وتدفع الجيران بعيداً؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -86,7 +86,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "box-sizing", "expected": "border-box" },
|
||||
"message": "اضبط <kbd>box-sizing: border-box</kbd>"
|
||||
"message": "ما قيمة <kbd>box-sizing</kbd> التي تشمل الحشو والحدود في العرض الإجمالي للعنصر؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -107,7 +107,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "padding:\\s*8px\\s+1rem",
|
||||
"message": "اضبط <kbd>padding: 8px 1rem</kbd>",
|
||||
"message": "استخدم اختصار <kbd>padding</kbd> بقيمتين: عمودي ثم أفقي",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -129,7 +129,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "margin:\\s*0\\s+auto",
|
||||
"message": "اضبط <kbd>margin: 0 auto</kbd>",
|
||||
"message": "استخدم <kbd>margin</kbd> مع كلمة مفتاحية تحسب تلقائياً مسافات متساوية يميناً ويساراً",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -151,7 +151,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "border-radius", "expected": "50%" },
|
||||
"message": "اضبط <kbd>border-radius: 50%</kbd>"
|
||||
"message": "ما نسبة <kbd>border-radius</kbd> التي تُنشئ دائرة كاملة من عنصر مربع؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -172,18 +172,18 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "اضبط <kbd>padding: 1rem</kbd>"
|
||||
"message": "أضف مساحة داخلية لبطاقة الإشعار"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "border-left:\\s*4px\\s+solid\\s+coral",
|
||||
"message": "اضبط <kbd>border-left: 4px solid coral</kbd>",
|
||||
"message": "أضف لمسة حدود يسارية باستخدام اختصار <kbd>border-left</kbd>",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "border-radius", "expected": "4px" },
|
||||
"message": "اضبط <kbd>border-radius: 4px</kbd>"
|
||||
"message": "دوّر الزوايا قليلاً باستخدام <kbd>border-radius</kbd>"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "max-width", "expected": "40rem" },
|
||||
"message": "اضبط <kbd>max-width: 40rem</kbd>"
|
||||
"message": "ما الخاصية التي تحدّ من عرض العنصر؟ جرّب قيمة بوحدة <kbd>rem</kbd> لطول سطر مقروء."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -43,13 +43,13 @@
|
||||
{
|
||||
"type": "contains",
|
||||
"value": "--brand",
|
||||
"message": "عرّف المتغير <kbd>--brand</kbd>",
|
||||
"message": "عرّف متغير <kbd>--brand</kbd>",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
"type": "contains",
|
||||
"value": "steelblue",
|
||||
"message": "اضبط القيمة على <kbd>steelblue</kbd>",
|
||||
"message": "اضبط القيمة إلى <kbd>steelblue</kbd>",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -71,7 +71,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "width:\\s*calc\\(\\s*100%\\s*-\\s*200px\\s*\\)",
|
||||
"message": "اضبط <kbd>width: calc(100% - 200px)</kbd>",
|
||||
"message": "استخدم <kbd>calc()</kbd> لطرح عرض الشريط الجانبي الثابت من عرض الحاوية الكامل.",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -93,7 +93,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "min-height", "expected": "100vh" },
|
||||
"message": "اضبط <kbd>min-height: 100vh</kbd>"
|
||||
"message": "ما الخاصية التي تضمن حداً أدنى للارتفاع؟ استخدم وحدة viewport لتغطية الشاشة بالكامل."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "transition:\\s*background-color\\s*0\\.3s",
|
||||
"message": "اضبط <kbd>transition: background-color 0.3s</kbd>",
|
||||
"message": "حدد أي خاصية تريد تحريكها وكم من الوقت يجب أن تستغرق.",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -56,7 +56,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "transition-timing-function", "expected": "ease-in-out" },
|
||||
"message": "اضبط التوقيت على <kbd>ease-in-out</kbd>"
|
||||
"message": "ما كلمة التسهيل التي تبدأ بطيئة، تتسارع، ثم تبطئ مرة أخرى؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -95,7 +95,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "animation:.*bounce.*1s.*infinite",
|
||||
"message": "طبّق <kbd>animation: bounce 1s infinite</kbd>",
|
||||
"message": "استخدم اختصار <kbd>animation</kbd>: الاسم، المدة، وعدد التكرار.",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -117,27 +117,27 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-name", "expected": "pulse" },
|
||||
"message": "اضبط <kbd>animation-name: pulse</kbd>"
|
||||
"message": "ما الخاصية التي تربط العنصر بقاعدة <kbd>@keyframes</kbd> مسماة؟"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-duration", "expected": "2s" },
|
||||
"message": "اضبط <kbd>animation-duration: 2s</kbd>"
|
||||
"message": "كم يجب أن تستغرق دورة كاملة من الحركة؟"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-delay", "expected": "1s" },
|
||||
"message": "اضبط <kbd>animation-delay: 1s</kbd>"
|
||||
"message": "ما الخاصية التي تجعل الحركة تنتظر قبل أن تبدأ؟"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-iteration-count", "expected": "2" },
|
||||
"message": "اضبط <kbd>animation-iteration-count: 2</kbd>"
|
||||
"message": "ما الخاصية التي تتحكم في عدد مرات تكرار الحركة؟"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-fill-mode", "expected": "forwards" },
|
||||
"message": "اضبط <kbd>animation-fill-mode: forwards</kbd>"
|
||||
"message": "ما الخاصية التي تُبقي العنصر بتنسيق حالته النهائية بعد انتهاء الحركة؟"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "@media\\s*\\(max-width:\\s*600px\\)",
|
||||
"message": "استخدم <kbd>@media (max-width: 600px)</kbd>",
|
||||
"message": "ابدأ بقاعدة <kbd>@media</kbd> — ما الشرط الذي يستهدف الشاشات بعرض 600px أو أقل؟",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
@@ -34,7 +34,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "lightcoral" },
|
||||
"message": "اضبط <kbd>background: lightcoral</kbd>",
|
||||
"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": "اضبط <kbd>font-size: 5vw</kbd>" }
|
||||
{
|
||||
"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": "اضبط <kbd>display: grid</kbd>"
|
||||
"message": "ما وضع العرض الذي يتيح لك تعريف صفوف وأعمدة؟"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "repeat\\(auto-fit,\\s*minmax\\(200px,\\s*1fr\\)\\)",
|
||||
"message": "استخدم <kbd>repeat(auto-fit, minmax(200px, 1fr))</kbd>",
|
||||
"message": "جرّب <kbd>repeat()</kbd> مع <kbd>auto-fit</kbd> و <kbd>minmax()</kbd> — ما الحد الأدنى والأقصى للحجم لإنشاء أعمدة مرنة؟",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "gap", "expected": "1rem" },
|
||||
"message": "اضبط <kbd>gap: 1rem</kbd>"
|
||||
"message": "ما الخاصية التي تضيف مساحة بين عناصر الشبكة؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -105,7 +109,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "@media\\s*\\(min-width:\\s*768px\\)",
|
||||
"message": "استخدم <kbd>@media (min-width: 768px)</kbd>",
|
||||
"message": "ما شرط <kbd>@media</kbd> الذي يُطبّق الأنماط عندما يكون عرض viewport على الأقل 768px؟",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
@@ -117,7 +121,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "width", "expected": "250px" },
|
||||
"message": "اضبط <kbd>width: 250px</kbd>",
|
||||
"message": "ما الخاصية التي تتحكم في عرض الشريط الجانبي على الشاشات الكبيرة؟",
|
||||
"options": { "exact": false }
|
||||
}
|
||||
]
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "display", "expected": "flex" },
|
||||
"message": "اضبط <kbd>display: flex</kbd>"
|
||||
"message": "ما قيمة display التي تحوّل العنصر إلى حاوية صندوق مرن؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -43,7 +43,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "gap", "expected": "1rem" },
|
||||
"message": "اضبط <kbd>gap: 1rem</kbd>"
|
||||
"message": "ما الخاصية التي تُنشئ تباعداً بين عناصر flex بدون استخدام الهوامش؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -64,7 +64,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "justify-content", "expected": "space-between" },
|
||||
"message": "اضبط <kbd>justify-content: space-between</kbd>"
|
||||
"message": "ما قيمة <kbd>justify-content</kbd> التي تدفع العنصر الأول والأخير إلى الحواف المتقابلة؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -85,7 +85,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "align-items", "expected": "center" },
|
||||
"message": "اضبط <kbd>align-items: center</kbd>"
|
||||
"message": "ما الخاصية التي تُحاذي عناصر flex على طول المحور المتقاطع؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -106,7 +106,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "flex-wrap", "expected": "wrap" },
|
||||
"message": "اضبط <kbd>flex-wrap: wrap</kbd>"
|
||||
"message": "ما الخاصية التي تسمح لعناصر flex بالتدفق إلى أسطر متعددة؟"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -127,7 +127,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "flex", "expected": "1" },
|
||||
"message": "اضبط <kbd>flex: 1</kbd>"
|
||||
"message": "ما الخاصية التي تجعل عنصر flex ينمو لملء المساحة المتبقية؟"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "coral" },
|
||||
"message": "Füge <kbd>color: coral;</kbd> hinzu"
|
||||
"message": "Welche Eigenschaft ändert die Textfarbe?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -43,12 +43,12 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "lavender" },
|
||||
"message": "Füge <kbd>background: lavender;</kbd> hinzu"
|
||||
"message": "Welche Eigenschaft steuert die Hintergrundfarbe?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "Füge <kbd>padding: 1rem;</kbd> hinzu"
|
||||
"message": "Das Element benötigt auch Innenabstand -- überprüfe die <kbd>padding</kbd>-Eigenschaft"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -74,7 +74,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "steelblue" },
|
||||
"message": "Setze <kbd>color: steelblue</kbd>"
|
||||
"message": "Überprüfe die <kbd>color</kbd>-Eigenschaft -- welcher Farbwert wurde in der Beschreibung genannt?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -100,7 +100,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "coral" },
|
||||
"message": "Setze <kbd>color: coral</kbd>"
|
||||
"message": "Überprüfe die <kbd>color</kbd>-Eigenschaft -- welche Farbe sollen die Links haben?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -126,7 +126,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "tomato" },
|
||||
"message": "Setze <kbd>background: tomato</kbd>"
|
||||
"message": "Überprüfe die <kbd>background</kbd>-Eigenschaft -- welche Farbe soll das Badge haben?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -152,7 +152,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "steelblue" },
|
||||
"message": "Setze <kbd>background: steelblue</kbd>"
|
||||
"message": "Überprüfe die <kbd>background</kbd>-Eigenschaft -- welche Farbe soll der primäre Button haben?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -178,7 +178,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "text-decoration", "expected": "none" },
|
||||
"message": "Setze <kbd>text-decoration: none</kbd>"
|
||||
"message": "Welche Eigenschaft entfernt die Unterstreichung von Links?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -199,7 +199,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "steelblue" },
|
||||
"message": "Setze <kbd>color: steelblue</kbd>"
|
||||
"message": "Welche Eigenschaft ändert die Textfarbe der Überschriften?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -225,7 +225,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "white" },
|
||||
"message": "Setze <kbd>color: white</kbd>"
|
||||
"message": "Überprüfe die <kbd>color</kbd>-Eigenschaft -- welche Farbe passt zu einem dunklen Hintergrund?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -251,7 +251,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "font-size", "expected": "0.9rem" },
|
||||
"message": "Setze <kbd>font-size: 0.9rem</kbd>"
|
||||
"message": "Welche Eigenschaft steuert die Schriftgröße?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"property": "background-color",
|
||||
"expected": "lightblue"
|
||||
},
|
||||
"message": "Setze die Hintergrundfarbe auf <kbd>lightblue</kbd>"
|
||||
"message": "Überprüfe die <kbd>background-color</kbd>-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 <kbd>2px solid blue</kbd>"
|
||||
"message": "Das Element benötigt einen Rahmen -- überprüfe die <kbd>border</kbd>-Eigenschaft"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
@@ -101,7 +101,7 @@
|
||||
"property": "color",
|
||||
"expected": "green"
|
||||
},
|
||||
"message": "Setze die Textfarbe auf <kbd>green</kbd>"
|
||||
"message": "Überprüfe die <kbd>color</kbd>-Eigenschaft -- welche Farbe kennzeichnet sichere Links?"
|
||||
},
|
||||
{
|
||||
"type": "contains",
|
||||
@@ -114,7 +114,7 @@
|
||||
"property": "text-decoration",
|
||||
"expected": "underline"
|
||||
},
|
||||
"message": "Setze text-decoration auf <kbd>underline</kbd>, um HTTPS-Links zu unterstreichen"
|
||||
"message": "Welcher <kbd>text-decoration</kbd>-Wert macht Links visuell hervorgehoben?"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
@@ -159,7 +159,7 @@
|
||||
"property": "background-color",
|
||||
"expected": "cornflowerblue"
|
||||
},
|
||||
"message": "Setze background-color auf <kbd>cornflowerblue</kbd> für das Hauptmenü-Styling"
|
||||
"message": "Überprüfe die <kbd>background-color</kbd>-Eigenschaft für die Hauptmenüpunkte"
|
||||
},
|
||||
{
|
||||
"type": "contains",
|
||||
@@ -172,7 +172,7 @@
|
||||
"property": "color",
|
||||
"expected": "white"
|
||||
},
|
||||
"message": "Setze die Textfarbe auf <kbd>white</kbd> 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 <kbd>none</kbd>"
|
||||
"message": "Welcher <kbd>text-decoration</kbd>-Wert entfernt die Unterstreichung?"
|
||||
},
|
||||
{
|
||||
"type": "contains",
|
||||
@@ -230,7 +230,7 @@
|
||||
"property": "color",
|
||||
"expected": "blue"
|
||||
},
|
||||
"message": "Setze color auf <kbd>blue</kbd>"
|
||||
"message": "Überprüfe die <kbd>color</kbd>-Eigenschaft für die Links"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
@@ -275,7 +275,7 @@
|
||||
"property": "margin-top",
|
||||
"expected": "0"
|
||||
},
|
||||
"message": "Setze margin-top auf <kbd>0</kbd>"
|
||||
"message": "Welcher Wert bei <kbd>margin-top</kbd> entfernt den oberen Abstand?"
|
||||
},
|
||||
{
|
||||
"type": "contains",
|
||||
@@ -288,7 +288,7 @@
|
||||
"property": "font-style",
|
||||
"expected": "italic"
|
||||
},
|
||||
"message": "Setze font-style auf <kbd>italic</kbd>"
|
||||
"message": "Welcher <kbd>font-style</kbd>-Wert macht den Text kursiv?"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
@@ -333,7 +333,7 @@
|
||||
"property": "color",
|
||||
"expected": "gray"
|
||||
},
|
||||
"message": "Setze color auf <kbd>gray</kbd>"
|
||||
"message": "Überprüfe die <kbd>color</kbd>-Eigenschaft -- welche Farbe sollen die Absätze haben?"
|
||||
},
|
||||
{
|
||||
"type": "contains",
|
||||
@@ -346,7 +346,7 @@
|
||||
"property": "padding-left",
|
||||
"expected": "20px"
|
||||
},
|
||||
"message": "Setze padding-left auf <kbd>20px</kbd>"
|
||||
"message": "Das Element benötigt eine Einrückung -- überprüfe die <kbd>padding-left</kbd>-Eigenschaft"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
@@ -391,7 +391,7 @@
|
||||
"property": "background-color",
|
||||
"expected": "darkblue"
|
||||
},
|
||||
"message": "Setze background-color auf <kbd>darkblue</kbd>"
|
||||
"message": "Welche Hintergrundfarbe soll der Button beim Hover haben?"
|
||||
},
|
||||
{
|
||||
"type": "contains",
|
||||
@@ -404,7 +404,7 @@
|
||||
"property": "color",
|
||||
"expected": "white"
|
||||
},
|
||||
"message": "Setze color auf <kbd>white</kbd>"
|
||||
"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 <kbd>bold</kbd>"
|
||||
"message": "Welcher <kbd>font-weight</kbd>-Wert macht Text fett?"
|
||||
},
|
||||
{
|
||||
"type": "contains",
|
||||
@@ -462,7 +462,7 @@
|
||||
"property": "margin-top",
|
||||
"expected": "0"
|
||||
},
|
||||
"message": "Setze margin-top auf <kbd>0</kbd>"
|
||||
"message": "Welcher Wert entfernt den oberen Abstand vollständig?"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "Setze <kbd>padding: 1rem</kbd>"
|
||||
"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 <kbd>border-left: 4px solid steelblue</kbd>",
|
||||
"message": "Überprüfe die <kbd>border-left</kbd>-Eigenschaft -- welche drei Werte braucht sie?",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -65,7 +65,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "margin-bottom", "expected": "1rem" },
|
||||
"message": "Setze <kbd>margin-bottom: 1rem</kbd>"
|
||||
"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 <kbd>box-sizing: border-box</kbd>"
|
||||
"message": "Welcher <kbd>box-sizing</kbd>-Wert bezieht Padding und Rahmen in die Breite ein?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -107,7 +107,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "padding:\\s*8px\\s+1rem",
|
||||
"message": "Setze <kbd>padding: 8px 1rem</kbd>",
|
||||
"message": "Überprüfe die <kbd>padding</kbd>-Kurzschreibweise -- zwei Werte setzen vertikal und horizontal",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -129,7 +129,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "margin:\\s*0\\s+auto",
|
||||
"message": "Setze <kbd>margin: 0 auto</kbd>",
|
||||
"message": "Welche <kbd>margin</kbd>-Kurzschreibweise zentriert ein Block-Element horizontal?",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -151,7 +151,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "border-radius", "expected": "50%" },
|
||||
"message": "Setze <kbd>border-radius: 50%</kbd>"
|
||||
"message": "Welcher <kbd>border-radius</kbd>-Wert macht ein quadratisches Element rund?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -172,18 +172,18 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "Setze <kbd>padding: 1rem</kbd>"
|
||||
"message": "Das Element benötigt Innenabstand -- überprüfe die <kbd>padding</kbd>-Eigenschaft"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "border-left:\\s*4px\\s+solid\\s+coral",
|
||||
"message": "Setze <kbd>border-left: 4px solid coral</kbd>",
|
||||
"message": "Überprüfe die <kbd>border-left</kbd>-Eigenschaft -- sie braucht Breite, Stil und Farbe",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "border-radius", "expected": "4px" },
|
||||
"message": "Setze <kbd>border-radius: 4px</kbd>"
|
||||
"message": "Das Element benötigt abgerundete Ecken -- überprüfe die <kbd>border-radius</kbd>-Eigenschaft"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "max-width", "expected": "40rem" },
|
||||
"message": "Setze <kbd>max-width: 40rem</kbd>"
|
||||
"message": "Welche Eigenschaft begrenzt die maximale Breite eines Elements?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -49,7 +49,7 @@
|
||||
{
|
||||
"type": "contains",
|
||||
"value": "steelblue",
|
||||
"message": "Setze den Wert auf <kbd>steelblue</kbd>",
|
||||
"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 <kbd>width: calc(100% - 200px)</kbd>",
|
||||
"message": "Überprüfe die <kbd>width</kbd>-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 <kbd>min-height: 100vh</kbd>"
|
||||
"message": "Welche Eigenschaft setzt die Mindesthöhe? Welche Viewport-Einheit entspricht 100% der Fensterhöhe?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "transition:\\s*background-color\\s*0\\.3s",
|
||||
"message": "Setze <kbd>transition: background-color 0.3s</kbd>",
|
||||
"message": "Überprüfe die <kbd>transition</kbd>-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 <kbd>ease-in-out</kbd>"
|
||||
"message": "Welche Timing-Funktion startet und endet langsam?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -117,27 +117,27 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-name", "expected": "pulse" },
|
||||
"message": "Setze <kbd>animation-name: pulse</kbd>"
|
||||
"message": "Welche Animation soll angewendet werden? Überprüfe den <kbd>@keyframes</kbd>-Namen."
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-duration", "expected": "2s" },
|
||||
"message": "Setze <kbd>animation-duration: 2s</kbd>"
|
||||
"message": "Welche Eigenschaft steuert die Dauer der Animation?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-delay", "expected": "1s" },
|
||||
"message": "Setze <kbd>animation-delay: 1s</kbd>"
|
||||
"message": "Welche Eigenschaft verzögert den Start der Animation?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-iteration-count", "expected": "2" },
|
||||
"message": "Setze <kbd>animation-iteration-count: 2</kbd>"
|
||||
"message": "Welche Eigenschaft steuert, wie oft die Animation wiederholt wird?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-fill-mode", "expected": "forwards" },
|
||||
"message": "Setze <kbd>animation-fill-mode: forwards</kbd>"
|
||||
"message": "Welcher <kbd>animation-fill-mode</kbd>-Wert behält den Endzustand bei?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "lightcoral" },
|
||||
"message": "Setze <kbd>background: lightcoral</kbd>",
|
||||
"message": "Überprüfe die <kbd>background</kbd>-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 <kbd>font-size: 5vw</kbd>" }
|
||||
{
|
||||
"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 <kbd>display: grid</kbd>"
|
||||
"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 <kbd>gap: 1rem</kbd>"
|
||||
"message": "Welche Eigenschaft steuert den Abstand zwischen Grid-Zellen?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -117,7 +121,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "width", "expected": "250px" },
|
||||
"message": "Setze <kbd>width: 250px</kbd>",
|
||||
"message": "Überprüfe die <kbd>width</kbd>-Eigenschaft für die Sidebar",
|
||||
"options": { "exact": false }
|
||||
}
|
||||
]
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "bg-blue-500",
|
||||
"message": "Füge die <kbd>bg-blue-500</kbd>-Klasse für einen blauen Hintergrund hinzu."
|
||||
"message": "Welche Tailwind-Klasse setzt eine blaue Hintergrundfarbe? Denke an das <kbd>bg-{farbe}-{abstufung}</kbd>-Muster."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -38,22 +38,22 @@
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "bg-white",
|
||||
"message": "Füge <kbd>bg-white</kbd> hinzu, um die Hintergrundfarbe auf weiß zu setzen."
|
||||
"message": "Das Element benötigt einen weißen Hintergrund -- welches <kbd>bg-</kbd>-Utility passt?"
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "p-4",
|
||||
"message": "Füge <kbd>p-4</kbd> hinzu, um 1rem Padding auf allen Seiten anzuwenden."
|
||||
"message": "Welches <kbd>p-</kbd>-Utility erzeugt 1rem Padding auf allen Seiten?"
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "rounded",
|
||||
"message": "Füge <kbd>rounded</kbd> 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 <kbd>shadow-sm</kbd> hinzu, um einen kleinen Schlagschatten anzuwenden."
|
||||
"message": "Das Element benötigt einen kleinen Schatten -- welches <kbd>shadow-</kbd>-Utility passt?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -71,17 +71,17 @@
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "text-blue-600",
|
||||
"message": "Füge <kbd>text-blue-600</kbd> hinzu, um den Text blau zu machen"
|
||||
"message": "Welches <kbd>text-</kbd>-Utility setzt eine blaue Textfarbe? Denke an das <kbd>text-{farbe}-{abstufung}</kbd>-Muster."
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "text-2xl",
|
||||
"message": "Füge <kbd>text-2xl</kbd> hinzu, um die Schriftgröße auf 1.5rem zu erhöhen"
|
||||
"message": "Welches <kbd>text-</kbd>-Utility setzt die Schriftgröße auf 1.5rem?"
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "font-bold",
|
||||
"message": "Füge <kbd>font-bold</kbd> hinzu, um den Text fett zu machen (font-weight: 700)"
|
||||
"message": "Welches <kbd>font-</kbd>-Utility macht den Text fett?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -99,17 +99,17 @@
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "px-6",
|
||||
"message": "Füge <kbd>px-6</kbd> für horizontales Padding hinzu (1.5rem links und rechts)"
|
||||
"message": "Welches <kbd>px-</kbd>-Utility erzeugt 1.5rem horizontales Padding?"
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "py-3",
|
||||
"message": "Füge <kbd>py-3</kbd> für vertikales Padding hinzu (0.75rem oben und unten)"
|
||||
"message": "Welches <kbd>py-</kbd>-Utility erzeugt 0.75rem vertikales Padding?"
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "mx-auto",
|
||||
"message": "Füge <kbd>mx-auto</kbd> hinzu, um den Button horizontal zu zentrieren"
|
||||
"message": "Welches <kbd>mx-</kbd>-Utility zentriert ein Element horizontal?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -127,32 +127,32 @@
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "w-full",
|
||||
"message": "Füge <kbd>w-full</kbd> 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 <kbd>md:w-1/2</kbd> für 50% Breite auf Tablet und größer hinzu"
|
||||
"message": "Welches responsive Breiten-Utility setzt 50% ab dem <kbd>md:</kbd>-Breakpoint?"
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "lg:w-1/3",
|
||||
"message": "Füge <kbd>lg:w-1/3</kbd> für 33.33% Breite auf Desktop und größer hinzu"
|
||||
"message": "Welches responsive Breiten-Utility setzt 33.33% ab dem <kbd>lg:</kbd>-Breakpoint?"
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "text-lg",
|
||||
"message": "Füge <kbd>text-lg</kbd> für die Basis-Textgröße hinzu"
|
||||
"message": "Welches <kbd>text-</kbd>-Utility setzt die Basis-Textgröße auf 1.125rem?"
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "md:text-xl",
|
||||
"message": "Füge <kbd>md:text-xl</kbd> für größeren Text auf Tablets hinzu"
|
||||
"message": "Welches responsive Text-Utility setzt eine größere Schrift ab dem <kbd>md:</kbd>-Breakpoint?"
|
||||
},
|
||||
{
|
||||
"type": "contains_class",
|
||||
"value": "lg:text-2xl",
|
||||
"message": "Füge <kbd>lg:text-2xl</kbd> für noch größeren Text auf Desktop hinzu"
|
||||
"message": "Welches responsive Text-Utility setzt die größte Schrift ab dem <kbd>lg:</kbd>-Breakpoint?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "display", "expected": "flex" },
|
||||
"message": "Setze <kbd>display: flex</kbd>"
|
||||
"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 <kbd>gap: 1rem</kbd>"
|
||||
"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 <kbd>justify-content: space-between</kbd>"
|
||||
"message": "Welcher <kbd>justify-content</kbd>-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 <kbd>align-items: center</kbd>"
|
||||
"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 <kbd>flex-wrap: wrap</kbd>"
|
||||
"message": "Welche Eigenschaft erlaubt Flex-Items, auf mehrere Zeilen umzubrechen?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -127,7 +127,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "flex", "expected": "1" },
|
||||
"message": "Setze <kbd>flex: 1</kbd>"
|
||||
"message": "Welche Eigenschaft lässt ein Flex-Item wachsen, um den verbleibenden Platz zu füllen?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "coral" },
|
||||
"message": "Añade <kbd>color: coral;</kbd>"
|
||||
"message": "¿Qué propiedad controla el color del texto?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -43,12 +43,12 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "lavender" },
|
||||
"message": "Añade <kbd>background: lavender;</kbd>"
|
||||
"message": "Revisa la propiedad <kbd>background</kbd>"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "Añade <kbd>padding: 1rem;</kbd>"
|
||||
"message": "La tarjeta necesita espacio dentro de sus bordes"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -74,7 +74,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "steelblue" },
|
||||
"message": "Establece <kbd>color: steelblue</kbd>"
|
||||
"message": "¿Qué propiedad cambia el color del texto?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -100,7 +100,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "coral" },
|
||||
"message": "Establece <kbd>color: coral</kbd>"
|
||||
"message": "¿Qué valor da un color cálido, rojo-anaranjado?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -126,7 +126,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "tomato" },
|
||||
"message": "Establece <kbd>background: tomato</kbd>"
|
||||
"message": "El badge necesita un fondo rojo brillante"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -152,7 +152,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "steelblue" },
|
||||
"message": "Establece <kbd>background: steelblue</kbd>"
|
||||
"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 <kbd>text-decoration: none</kbd>"
|
||||
"message": "¿Qué propiedad controla el subrayado de los enlaces?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -199,7 +199,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "steelblue" },
|
||||
"message": "Establece <kbd>color: steelblue</kbd>"
|
||||
"message": "Revisa la propiedad <kbd>color</kbd>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -225,7 +225,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "white" },
|
||||
"message": "Establece <kbd>color: white</kbd>"
|
||||
"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 <kbd>font-size: 0.9rem</kbd>"
|
||||
"message": "Revisa la propiedad <kbd>font-size</kbd> — el texto debería ser ligeramente más pequeño"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "Establece <kbd>padding: 1rem</kbd>"
|
||||
"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 <kbd>border-left: 4px solid steelblue</kbd>",
|
||||
"message": "Usa el atajo <kbd>border-left</kbd> 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 <kbd>margin-bottom: 1rem</kbd>"
|
||||
"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 <kbd>box-sizing: border-box</kbd>"
|
||||
"message": "¿Qué valor de <kbd>box-sizing</kbd> incluye padding y borde en el ancho total del elemento?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -107,7 +107,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "padding:\\s*8px\\s+1rem",
|
||||
"message": "Establece <kbd>padding: 8px 1rem</kbd>",
|
||||
"message": "Usa el atajo <kbd>padding</kbd> con dos valores: vertical y luego horizontal",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -129,7 +129,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "margin:\\s*0\\s+auto",
|
||||
"message": "Establece <kbd>margin: 0 auto</kbd>",
|
||||
"message": "Usa <kbd>margin</kbd> 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 <kbd>border-radius: 50%</kbd>"
|
||||
"message": "¿Qué porcentaje de <kbd>border-radius</kbd> 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 <kbd>padding: 1rem</kbd>"
|
||||
"message": "El elemento necesita espacio interior"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "border-left:\\s*4px\\s+solid\\s+coral",
|
||||
"message": "Establece <kbd>border-left: 4px solid coral</kbd>",
|
||||
"message": "Añade un acento de borde izquierdo usando el atajo <kbd>border-left</kbd>",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "border-radius", "expected": "4px" },
|
||||
"message": "Establece <kbd>border-radius: 4px</kbd>"
|
||||
"message": "Redondea las esquinas ligeramente con <kbd>border-radius</kbd>"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "max-width", "expected": "40rem" },
|
||||
"message": "Establece <kbd>max-width: 40rem</kbd>"
|
||||
"message": "¿Qué propiedad limita el ancho de un elemento? Prueba un valor en <kbd>rem</kbd> para una longitud de línea legible."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -49,7 +49,7 @@
|
||||
{
|
||||
"type": "contains",
|
||||
"value": "steelblue",
|
||||
"message": "Establece el valor a <kbd>steelblue</kbd>",
|
||||
"message": "Asigna el valor <kbd>steelblue</kbd> a la variable",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -71,7 +71,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "width:\\s*calc\\(\\s*100%\\s*-\\s*200px\\s*\\)",
|
||||
"message": "Establece <kbd>width: calc(100% - 200px)</kbd>",
|
||||
"message": "Usa <kbd>calc()</kbd> 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 <kbd>min-height: 100vh</kbd>"
|
||||
"message": "¿Qué propiedad asegura una altura mínima? Usa una unidad de viewport para cobertura de pantalla completa."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "transition:\\s*background-color\\s*0\\.3s",
|
||||
"message": "Establece <kbd>transition: background-color 0.3s</kbd>",
|
||||
"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 <kbd>ease-in-out</kbd>"
|
||||
"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 <kbd>animation: bounce 1s infinite</kbd>",
|
||||
"message": "Usa el atajo <kbd>animation</kbd>: 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 <kbd>animation-name: pulse</kbd>"
|
||||
"message": "¿Qué propiedad vincula un elemento a una regla <kbd>@keyframes</kbd> nombrada?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-duration", "expected": "2s" },
|
||||
"message": "Establece <kbd>animation-duration: 2s</kbd>"
|
||||
"message": "¿Cuánto debe durar un ciclo completo de la animación?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-delay", "expected": "1s" },
|
||||
"message": "Establece <kbd>animation-delay: 1s</kbd>"
|
||||
"message": "¿Qué propiedad hace que la animación espere antes de comenzar?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-iteration-count", "expected": "2" },
|
||||
"message": "Establece <kbd>animation-iteration-count: 2</kbd>"
|
||||
"message": "¿Qué propiedad controla cuántas veces se repite la animación?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-fill-mode", "expected": "forwards" },
|
||||
"message": "Establece <kbd>animation-fill-mode: forwards</kbd>"
|
||||
"message": "¿Qué propiedad mantiene el elemento con los estilos de su último keyframe después de que termina la animación?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "@media\\s*\\(max-width:\\s*600px\\)",
|
||||
"message": "Usa <kbd>@media (max-width: 600px)</kbd>",
|
||||
"message": "Empieza con una regla <kbd>@media</kbd> — ¿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 <kbd>background: lightcoral</kbd>",
|
||||
"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 <kbd>font-size: 5vw</kbd>"
|
||||
"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 <kbd>display: grid</kbd>"
|
||||
"message": "¿Qué modo de display permite definir filas y columnas?"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "repeat\\(auto-fit,\\s*minmax\\(200px,\\s*1fr\\)\\)",
|
||||
"message": "Usa <kbd>repeat(auto-fit, minmax(200px, 1fr))</kbd>",
|
||||
"message": "Prueba <kbd>repeat()</kbd> con <kbd>auto-fit</kbd> y <kbd>minmax()</kbd> — ¿qué tamaños mínimo y máximo crean columnas flexibles?",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "gap", "expected": "1rem" },
|
||||
"message": "Establece <kbd>gap: 1rem</kbd>"
|
||||
"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 <kbd>@media (min-width: 768px)</kbd>",
|
||||
"message": "¿Qué condición <kbd>@media</kbd> 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 <kbd>width: 250px</kbd>",
|
||||
"message": "¿Qué propiedad controla el ancho de la barra lateral en pantallas más grandes?",
|
||||
"options": { "exact": false }
|
||||
}
|
||||
]
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "display", "expected": "flex" },
|
||||
"message": "Establece <kbd>display: flex</kbd>"
|
||||
"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 <kbd>gap: 1rem</kbd>"
|
||||
"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 <kbd>justify-content: space-between</kbd>"
|
||||
"message": "¿Qué valor de <kbd>justify-content</kbd> 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 <kbd>align-items: center</kbd>"
|
||||
"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 <kbd>flex-wrap: wrap</kbd>"
|
||||
"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 <kbd>flex: 1</kbd>"
|
||||
"message": "¿Qué propiedad hace que un elemento flex crezca para llenar el espacio restante?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "display", "expected": "flex" },
|
||||
"message": "Set <kbd>display: flex</kbd>"
|
||||
"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 <kbd>gap: 1rem</kbd>"
|
||||
"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 <kbd>justify-content: space-between</kbd>"
|
||||
"message": "Which <kbd>justify-content</kbd> 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 <kbd>align-items: center</kbd>"
|
||||
"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 <kbd>flex-wrap: wrap</kbd>"
|
||||
"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 <kbd>flex: 1</kbd>"
|
||||
"message": "Which property makes a flex item grow to fill the remaining space?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "display", "expected": "grid" },
|
||||
"message": "Set <kbd>display: grid</kbd>"
|
||||
"message": "Which <kbd>display</kbd> 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 <kbd>grid-template-columns: repeat(3, 1fr)</kbd>",
|
||||
"message": "Which CSS property defines column sizes in a grid? Use <kbd>repeat()</kbd> with the <kbd>fr</kbd> unit for equal columns.",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -65,7 +65,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "gap", "expected": "1rem" },
|
||||
"message": "Set <kbd>gap: 1rem</kbd>"
|
||||
"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 <kbd>grid-column: span 2</kbd>",
|
||||
"message": "Which CSS property makes a grid item stretch across multiple columns? Use the <kbd>span</kbd> 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 <kbd>grid-template-columns: repeat(auto-fit, minmax(150px, 1fr))</kbd>",
|
||||
"message": "Which CSS property creates responsive columns? Combine <kbd>auto-fit</kbd> with <kbd>minmax()</kbd> for flexible sizing.",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "coral" },
|
||||
"message": "Dodaj <kbd>color: coral;</kbd>"
|
||||
"message": "Która właściwość kontroluje kolor tekstu?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -43,12 +43,12 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "lavender" },
|
||||
"message": "Dodaj <kbd>background: lavender;</kbd>"
|
||||
"message": "Sprawdź właściwość <kbd>background</kbd> — jaki kolor potrzebuje karta?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "Dodaj <kbd>padding: 1rem;</kbd>"
|
||||
"message": "Element potrzebuje wewnętrznej przestrzeni — sprawdź właściwość <kbd>padding</kbd>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -74,7 +74,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "steelblue" },
|
||||
"message": "Ustaw <kbd>color: steelblue</kbd>"
|
||||
"message": "Która właściwość kontroluje kolor tekstu?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -100,7 +100,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "coral" },
|
||||
"message": "Ustaw <kbd>color: coral</kbd>"
|
||||
"message": "Sprawdź właściwość <kbd>color</kbd> — jaki kolor potrzebują linki?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -126,7 +126,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "tomato" },
|
||||
"message": "Ustaw <kbd>background: tomato</kbd>"
|
||||
"message": "Sprawdź właściwość <kbd>background</kbd> — jaki kolor potrzebuje badge?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -152,7 +152,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "steelblue" },
|
||||
"message": "Ustaw <kbd>background: steelblue</kbd>"
|
||||
"message": "Sprawdź właściwość <kbd>background</kbd> — jaki kolor potrzebuje przycisk?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -178,7 +178,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "text-decoration", "expected": "none" },
|
||||
"message": "Ustaw <kbd>text-decoration: none</kbd>"
|
||||
"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 <kbd>color: steelblue</kbd>"
|
||||
"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 <kbd>color: white</kbd>"
|
||||
"message": "Sprawdź właściwość <kbd>color</kbd> — jaki kolor potrzebują linki nawigacji?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -251,7 +251,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "font-size", "expected": "0.9rem" },
|
||||
"message": "Ustaw <kbd>font-size: 0.9rem</kbd>"
|
||||
"message": "Która właściwość kontroluje rozmiar tekstu?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "Ustaw <kbd>padding: 1rem</kbd>"
|
||||
"message": "Element potrzebuje wewnętrznej przestrzeni — sprawdź właściwość <kbd>padding</kbd>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -43,7 +43,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "border-left:\\s*4px\\s+solid\\s+steelblue",
|
||||
"message": "Ustaw <kbd>border-left: 4px solid steelblue</kbd>",
|
||||
"message": "Sprawdź właściwość <kbd>border-left</kbd> — 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 <kbd>margin-bottom: 1rem</kbd>"
|
||||
"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 <kbd>box-sizing: border-box</kbd>"
|
||||
"message": "Która wartość <kbd>box-sizing</kbd> włącza padding i ramkę do szerokości?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -107,7 +107,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "padding:\\s*8px\\s+1rem",
|
||||
"message": "Ustaw <kbd>padding: 8px 1rem</kbd>",
|
||||
"message": "Sprawdź skrót <kbd>padding</kbd> — dwie wartości oznaczają pion i poziom",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -129,7 +129,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "margin:\\s*0\\s+auto",
|
||||
"message": "Ustaw <kbd>margin: 0 auto</kbd>",
|
||||
"message": "Sprawdź skrót <kbd>margin</kbd> — jak automatycznie wycentrować element poziomo?",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -151,7 +151,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "border-radius", "expected": "50%" },
|
||||
"message": "Ustaw <kbd>border-radius: 50%</kbd>"
|
||||
"message": "Która wartość <kbd>border-radius</kbd> tworzy pełne koło?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -172,18 +172,18 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "Ustaw <kbd>padding: 1rem</kbd>"
|
||||
"message": "Element potrzebuje wewnętrznej przestrzeni — sprawdź właściwość <kbd>padding</kbd>"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "border-left:\\s*4px\\s+solid\\s+coral",
|
||||
"message": "Ustaw <kbd>border-left: 4px solid coral</kbd>",
|
||||
"message": "Sprawdź właściwość <kbd>border-left</kbd> — jaki styl akcentu potrzebuje powiadomienie?",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "border-radius", "expected": "4px" },
|
||||
"message": "Ustaw <kbd>border-radius: 4px</kbd>"
|
||||
"message": "Element potrzebuje zaokrąglonych rogów — sprawdź właściwość <kbd>border-radius</kbd>"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "max-width", "expected": "40rem" },
|
||||
"message": "Ustaw <kbd>max-width: 40rem</kbd>"
|
||||
"message": "Która właściwość ogranicza maksymalną szerokość elementu?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -49,7 +49,7 @@
|
||||
{
|
||||
"type": "contains",
|
||||
"value": "steelblue",
|
||||
"message": "Ustaw wartość na <kbd>steelblue</kbd>",
|
||||
"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 <kbd>width: calc(100% - 200px)</kbd>",
|
||||
"message": "Sprawdź funkcję <kbd>calc()</kbd> — jak obliczyć szerokość minus sidebar?",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -93,7 +93,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "min-height", "expected": "100vh" },
|
||||
"message": "Ustaw <kbd>min-height: 100vh</kbd>"
|
||||
"message": "Która właściwość zapewnia minimalną wysokość na cały viewport?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "transition:\\s*background-color\\s*0\\.3s",
|
||||
"message": "Ustaw <kbd>transition: background-color 0.3s</kbd>",
|
||||
"message": "Sprawdź właściwość <kbd>transition</kbd> — 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 <kbd>ease-in-out</kbd>"
|
||||
"message": "Która wartość tworzy płynne przyspieszenie i spowolnienie?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -83,7 +83,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "50%.*transform: translateY\\(-20px\\)",
|
||||
"message": "Przy <kbd>50%</kbd>, użyj <kbd>transform: translateY(-20px)</kbd>",
|
||||
"message": "W połowie animacji piłka powinna podskoczyć w górę — sprawdź <kbd>transform</kbd>",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
@@ -95,7 +95,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "animation:.*bounce.*1s.*infinite",
|
||||
"message": "Zastosuj <kbd>animation: bounce 1s infinite</kbd>",
|
||||
"message": "Sprawdź skrót <kbd>animation</kbd> — podaj nazwę, czas trwania i powtarzanie",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -117,27 +117,27 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-name", "expected": "pulse" },
|
||||
"message": "Ustaw <kbd>animation-name: pulse</kbd>"
|
||||
"message": "Która właściwość wskazuje nazwę animacji do zastosowania?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-duration", "expected": "2s" },
|
||||
"message": "Ustaw <kbd>animation-duration: 2s</kbd>"
|
||||
"message": "Sprawdź właściwość <kbd>animation-duration</kbd> — jak długo trwa jeden cykl?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-delay", "expected": "1s" },
|
||||
"message": "Ustaw <kbd>animation-delay: 1s</kbd>"
|
||||
"message": "Sprawdź właściwość <kbd>animation-delay</kbd> — ile czeka przed startem?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-iteration-count", "expected": "2" },
|
||||
"message": "Ustaw <kbd>animation-iteration-count: 2</kbd>"
|
||||
"message": "Sprawdź właściwość <kbd>animation-iteration-count</kbd> — ile razy ma się powtórzyć?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-fill-mode", "expected": "forwards" },
|
||||
"message": "Ustaw <kbd>animation-fill-mode: forwards</kbd>"
|
||||
"message": "Która wartość <kbd>animation-fill-mode</kbd> zachowuje końcowy stan animacji?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "lightcoral" },
|
||||
"message": "Ustaw <kbd>background: lightcoral</kbd>",
|
||||
"message": "Sprawdź właściwość <kbd>background</kbd> — 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 <kbd>font-size: 5vw</kbd>" }
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "font-size", "expected": "5vw" },
|
||||
"message": "Sprawdź właściwość <kbd>font-size</kbd> — która jednostka skaluje się z viewport?"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -73,7 +77,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "display", "expected": "grid" },
|
||||
"message": "Ustaw <kbd>display: grid</kbd>"
|
||||
"message": "Która wartość <kbd>display</kbd> włącza układ siatkowy?"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
@@ -84,7 +88,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "gap", "expected": "1rem" },
|
||||
"message": "Ustaw <kbd>gap: 1rem</kbd>"
|
||||
"message": "Sprawdź właściwość <kbd>gap</kbd> — jaki odstęp potrzebują elementy siatki?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -117,7 +121,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "width", "expected": "250px" },
|
||||
"message": "Ustaw <kbd>width: 250px</kbd>",
|
||||
"message": "Sprawdź właściwość <kbd>width</kbd> — jaką stałą szerokość potrzebuje sidebar?",
|
||||
"options": { "exact": false }
|
||||
}
|
||||
]
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "display", "expected": "flex" },
|
||||
"message": "Ustaw <kbd>display: flex</kbd>"
|
||||
"message": "Która właściwość <kbd>display</kbd> tworzy kontener flex?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -43,7 +43,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "gap", "expected": "1rem" },
|
||||
"message": "Ustaw <kbd>gap: 1rem</kbd>"
|
||||
"message": "Sprawdź właściwość <kbd>gap</kbd> — jaki odstęp potrzebują elementy?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -64,7 +64,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "justify-content", "expected": "space-between" },
|
||||
"message": "Ustaw <kbd>justify-content: space-between</kbd>"
|
||||
"message": "Która wartość <kbd>justify-content</kbd> rozdziela elementy na końce?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -85,7 +85,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "align-items", "expected": "center" },
|
||||
"message": "Ustaw <kbd>align-items: center</kbd>"
|
||||
"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 <kbd>flex-wrap: wrap</kbd>"
|
||||
"message": "Sprawdź właściwość <kbd>flex-wrap</kbd> — jak pozwolić elementom przenosić się na nowe linie?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -127,7 +127,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "flex", "expected": "1" },
|
||||
"message": "Ustaw <kbd>flex: 1</kbd>"
|
||||
"message": "Sprawdź właściwość <kbd>flex</kbd> — jak sprawić, by element wypełnił dostępną przestrzeń?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "coral" },
|
||||
"message": "Додайте <kbd>color: coral;</kbd>"
|
||||
"message": "Яка властивість керує кольором тексту?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -43,12 +43,12 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "lavender" },
|
||||
"message": "Додайте <kbd>background: lavender;</kbd>"
|
||||
"message": "Перевірте властивість <kbd>background</kbd>"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "Додайте <kbd>padding: 1rem;</kbd>"
|
||||
"message": "Картка потребує простору всередині її меж"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -74,7 +74,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "steelblue" },
|
||||
"message": "Встановіть <kbd>color: steelblue</kbd>"
|
||||
"message": "Яка властивість змінює колір тексту?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -100,7 +100,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "coral" },
|
||||
"message": "Встановіть <kbd>color: coral</kbd>"
|
||||
"message": "Яке значення дає теплий червонувато-оранжевий колір?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -126,7 +126,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "tomato" },
|
||||
"message": "Встановіть <kbd>background: tomato</kbd>"
|
||||
"message": "Значку потрібен яскравий червоний фон"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -152,7 +152,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "steelblue" },
|
||||
"message": "Встановіть <kbd>background: steelblue</kbd>"
|
||||
"message": "Яка властивість встановлює колір заливки кнопки?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -178,7 +178,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "text-decoration", "expected": "none" },
|
||||
"message": "Встановіть <kbd>text-decoration: none</kbd>"
|
||||
"message": "Яка властивість керує підкресленням посилань?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -199,7 +199,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "steelblue" },
|
||||
"message": "Встановіть <kbd>color: steelblue</kbd>"
|
||||
"message": "Перевірте властивість <kbd>color</kbd>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -225,7 +225,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "color", "expected": "white" },
|
||||
"message": "Встановіть <kbd>color: white</kbd>"
|
||||
"message": "Посилання мають виділятися на синьому фоні"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -251,7 +251,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "font-size", "expected": "0.9rem" },
|
||||
"message": "Встановіть <kbd>font-size: 0.9rem</kbd>"
|
||||
"message": "Перевірте властивість <kbd>font-size</kbd> — текст має бути трохи меншим"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "Встановіть <kbd>padding: 1rem</kbd>"
|
||||
"message": "Яка властивість додає простір між вмістом елемента та його межею?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -43,7 +43,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "border-left:\\s*4px\\s+solid\\s+steelblue",
|
||||
"message": "Встановіть <kbd>border-left: 4px solid steelblue</kbd>",
|
||||
"message": "Використайте скорочення <kbd>border-left</kbd> зі значеннями ширини, стилю та кольору",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -65,7 +65,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "margin-bottom", "expected": "1rem" },
|
||||
"message": "Встановіть <kbd>margin-bottom: 1rem</kbd>"
|
||||
"message": "Яка властивість створює простір знизу елемента, відштовхуючи сусідів?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -86,7 +86,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "box-sizing", "expected": "border-box" },
|
||||
"message": "Встановіть <kbd>box-sizing: border-box</kbd>"
|
||||
"message": "Яке значення <kbd>box-sizing</kbd> включає padding та межу в загальну ширину елемента?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -107,7 +107,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "padding:\\s*8px\\s+1rem",
|
||||
"message": "Встановіть <kbd>padding: 8px 1rem</kbd>",
|
||||
"message": "Використайте скорочення <kbd>padding</kbd> з двома значеннями: вертикальне та горизонтальне",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -129,7 +129,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "margin:\\s*0\\s+auto",
|
||||
"message": "Встановіть <kbd>margin: 0 auto</kbd>",
|
||||
"message": "Використайте <kbd>margin</kbd> з ключовим словом, яке автоматично обчислює рівні ліві та праві відступи",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -151,7 +151,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "border-radius", "expected": "50%" },
|
||||
"message": "Встановіть <kbd>border-radius: 50%</kbd>"
|
||||
"message": "Який відсоток <kbd>border-radius</kbd> створює ідеальне коло з квадратного елемента?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -172,18 +172,18 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "padding", "expected": "1rem" },
|
||||
"message": "Встановіть <kbd>padding: 1rem</kbd>"
|
||||
"message": "Додайте внутрішній відступ до картки сповіщення"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "border-left:\\s*4px\\s+solid\\s+coral",
|
||||
"message": "Встановіть <kbd>border-left: 4px solid coral</kbd>",
|
||||
"message": "Додайте лівий акцент за допомогою скорочення <kbd>border-left</kbd>",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "border-radius", "expected": "4px" },
|
||||
"message": "Встановіть <kbd>border-radius: 4px</kbd>"
|
||||
"message": "Злегка заокругліть кути за допомогою <kbd>border-radius</kbd>"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "max-width", "expected": "40rem" },
|
||||
"message": "Встановіть <kbd>max-width: 40rem</kbd>"
|
||||
"message": "Яка властивість обмежує ширину елемента? Спробуйте значення в <kbd>rem</kbd> для комфортної довжини рядка."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -49,7 +49,7 @@
|
||||
{
|
||||
"type": "contains",
|
||||
"value": "steelblue",
|
||||
"message": "Встановіть значення <kbd>steelblue</kbd>",
|
||||
"message": "Встановіть значення на <kbd>steelblue</kbd>",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -71,7 +71,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "width:\\s*calc\\(\\s*100%\\s*-\\s*200px\\s*\\)",
|
||||
"message": "Встановіть <kbd>width: calc(100% - 200px)</kbd>",
|
||||
"message": "Використайте <kbd>calc()</kbd>, щоб відняти фіксовану ширину сайдбару від повної ширини контейнера.",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -93,7 +93,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "min-height", "expected": "100vh" },
|
||||
"message": "Встановіть <kbd>min-height: 100vh</kbd>"
|
||||
"message": "Яка властивість забезпечує мінімальну висоту? Використайте одиницю viewport для повноекранного покриття."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "transition:\\s*background-color\\s*0\\.3s",
|
||||
"message": "Встановіть <kbd>transition: background-color 0.3s</kbd>",
|
||||
"message": "Вкажіть, яку властивість анімувати та скільки це має тривати.",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -56,7 +56,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "transition-timing-function", "expected": "ease-in-out" },
|
||||
"message": "Встановіть timing на <kbd>ease-in-out</kbd>"
|
||||
"message": "Яке ключове слово пом'якшення починається повільно, прискорюється, а потім знову сповільнюється?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -95,7 +95,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "animation:.*bounce.*1s.*infinite",
|
||||
"message": "Застосуйте <kbd>animation: bounce 1s infinite</kbd>",
|
||||
"message": "Використайте скорочення <kbd>animation</kbd>: назва, тривалість та кількість повторень.",
|
||||
"options": { "caseSensitive": false }
|
||||
}
|
||||
]
|
||||
@@ -117,27 +117,27 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-name", "expected": "pulse" },
|
||||
"message": "Встановіть <kbd>animation-name: pulse</kbd>"
|
||||
"message": "Яка властивість пов'язує елемент з іменованим правилом <kbd>@keyframes</kbd>?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-duration", "expected": "2s" },
|
||||
"message": "Встановіть <kbd>animation-duration: 2s</kbd>"
|
||||
"message": "Скільки має тривати один повний цикл анімації?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-delay", "expected": "1s" },
|
||||
"message": "Встановіть <kbd>animation-delay: 1s</kbd>"
|
||||
"message": "Яка властивість змушує анімацію зачекати перед початком?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-iteration-count", "expected": "2" },
|
||||
"message": "Встановіть <kbd>animation-iteration-count: 2</kbd>"
|
||||
"message": "Яка властивість контролює кількість повторень анімації?"
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "animation-fill-mode", "expected": "forwards" },
|
||||
"message": "Встановіть <kbd>animation-fill-mode: forwards</kbd>"
|
||||
"message": "Яка властивість зберігає стиль елемента в його фінальному стані keyframe після завершення анімації?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "@media\\s*\\(max-width:\\s*600px\\)",
|
||||
"message": "Використайте <kbd>@media (max-width: 600px)</kbd>",
|
||||
"message": "Почніть з правила <kbd>@media</kbd> — яка умова націлюється на екрани шириною 600px або менше?",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
@@ -34,7 +34,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "background", "expected": "lightcoral" },
|
||||
"message": "Встановіть <kbd>background: lightcoral</kbd>",
|
||||
"message": "Яка властивість змінює колір фону елемента?",
|
||||
"options": { "exact": false }
|
||||
}
|
||||
]
|
||||
@@ -56,7 +56,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "font-size", "expected": "5vw" },
|
||||
"message": "Встановіть <kbd>font-size: 5vw</kbd>"
|
||||
"message": "Яка одиниця CSS масштабується відносно ширини viewport?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -77,18 +77,18 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "display", "expected": "grid" },
|
||||
"message": "Встановіть <kbd>display: grid</kbd>"
|
||||
"message": "Який режим display дозволяє визначати рядки та колонки?"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "repeat\\(auto-fit,\\s*minmax\\(200px,\\s*1fr\\)\\)",
|
||||
"message": "Використайте <kbd>repeat(auto-fit, minmax(200px, 1fr))</kbd>",
|
||||
"message": "Спробуйте <kbd>repeat()</kbd> з <kbd>auto-fit</kbd> та <kbd>minmax()</kbd> — які мінімальний та максимальний розміри створять гнучкі колонки?",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "gap", "expected": "1rem" },
|
||||
"message": "Встановіть <kbd>gap: 1rem</kbd>"
|
||||
"message": "Яка властивість додає простір між елементами grid?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -109,7 +109,7 @@
|
||||
{
|
||||
"type": "regex",
|
||||
"value": "@media\\s*\\(min-width:\\s*768px\\)",
|
||||
"message": "Використайте <kbd>@media (min-width: 768px)</kbd>",
|
||||
"message": "Яка умова <kbd>@media</kbd> застосовує стилі, коли viewport має ширину щонайменше 768px?",
|
||||
"options": { "caseSensitive": false }
|
||||
},
|
||||
{
|
||||
@@ -121,7 +121,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "width", "expected": "250px" },
|
||||
"message": "Встановіть <kbd>width: 250px</kbd>",
|
||||
"message": "Яка властивість контролює ширину сайдбару на великих екранах?",
|
||||
"options": { "exact": false }
|
||||
}
|
||||
]
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "display", "expected": "flex" },
|
||||
"message": "Встановіть <kbd>display: flex</kbd>"
|
||||
"message": "Яке значення display перетворює елемент на гнучкий контейнер?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -43,7 +43,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "gap", "expected": "1rem" },
|
||||
"message": "Встановіть <kbd>gap: 1rem</kbd>"
|
||||
"message": "Яка властивість створює відстань між flex-елементами без використання margin?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -64,7 +64,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "justify-content", "expected": "space-between" },
|
||||
"message": "Встановіть <kbd>justify-content: space-between</kbd>"
|
||||
"message": "Яке значення <kbd>justify-content</kbd> розміщує перший та останній елементи на протилежних краях?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -85,7 +85,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "align-items", "expected": "center" },
|
||||
"message": "Встановіть <kbd>align-items: center</kbd>"
|
||||
"message": "Яка властивість вирівнює flex-елементи вздовж поперечної осі?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -106,7 +106,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "flex-wrap", "expected": "wrap" },
|
||||
"message": "Встановіть <kbd>flex-wrap: wrap</kbd>"
|
||||
"message": "Яка властивість дозволяє flex-елементам переходити на кілька рядків?"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -127,7 +127,7 @@
|
||||
{
|
||||
"type": "property_value",
|
||||
"value": { "property": "flex", "expected": "1" },
|
||||
"message": "Встановіть <kbd>flex: 1</kbd>"
|
||||
"message": "Яка властивість змушує flex-елемент зростати, щоб заповнити залишковий простір?"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
87
specs/004-pedagogical-messages/plan.md
Normal file
87
specs/004-pedagogical-messages/plan.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Implementation Plan
|
||||
|
||||
## 1. Objective
|
||||
|
||||
Rewrite all answer-revealing validation error messages across lesson JSON files to use pedagogical hints (concept questions, property-name nudges, directional guidance) instead of literal CSS solutions. This eliminates the fail-then-copy anti-pattern and promotes genuine learning.
|
||||
|
||||
## 2. Approach
|
||||
|
||||
**Phase-based, content-first strategy:**
|
||||
|
||||
1. Define a message style guide with 3 hint categories:
|
||||
- **Concept question:** "Which property adds space inside an element?" (for property discovery)
|
||||
- **Property hint:** "Check the `padding` property" (when the property is known but value is wrong)
|
||||
- **Directional nudge:** "The items need to wrap to the next line" (for layout concepts)
|
||||
|
||||
2. Rewrite English priority modules first (flexbox, box-model, colors, positioning) — these are 100% answer-revealing and form the template for all other rewrites.
|
||||
|
||||
3. Rewrite remaining English modules, reusing the same hint patterns established in step 2.
|
||||
|
||||
4. Update localized variants with equivalent pedagogical messages in each target language (ar, de, es, pl, uk), translating the English hints while preserving natural phrasing in each language.
|
||||
|
||||
5. Run `npm run format.lessons` to ensure consistent formatting, then run tests.
|
||||
|
||||
## 3. File Mapping
|
||||
|
||||
### Files to modify (message field only, no validation logic changes):
|
||||
|
||||
**English priority (create → N/A, modify → 4, delete → N/A):**
|
||||
- `lessons/flexbox.json` — modify 6 messages
|
||||
- `lessons/01-box-model.json` — modify 10 messages
|
||||
- `lessons/03-colors.json` — modify 4 messages
|
||||
- `lessons/12-positioning.json` — modify 5 messages
|
||||
|
||||
**English remaining (modify → 13):**
|
||||
- `lessons/00-basics.json` — modify 4 messages
|
||||
- `lessons/00-basic-selectors.json` — modify 15 messages
|
||||
- `lessons/01-advanced-selectors.json` — modify 8 messages
|
||||
- `lessons/04-typography.json` — modify 1 message
|
||||
- `lessons/05-units-variables.json` — modify 3 messages
|
||||
- `lessons/06-transitions-animations.json` — modify 8 messages
|
||||
- `lessons/07-layouts.json` — modify 8 messages
|
||||
- `lessons/08-responsive.json` — modify 8 messages
|
||||
- `lessons/09-gradients.json` — modify 3 messages
|
||||
- `lessons/10-tailwind-basics.json` — modify 16 messages
|
||||
- `lessons/11-filters.json` — modify 4 messages
|
||||
- `lessons/13-pseudo-elements.json` — modify 4 messages
|
||||
- `lessons/grid.json` — modify 5 messages
|
||||
|
||||
**Localized variants (modify):**
|
||||
- `lessons/ar/flexbox.json`, `lessons/ar/01-box-model.json`, + other ar/ modules with answer-revealing messages
|
||||
- `lessons/de/flexbox.json`, `lessons/de/01-box-model.json`, + other de/ modules
|
||||
- `lessons/es/flexbox.json`, `lessons/es/01-box-model.json`, + other es/ modules
|
||||
- `lessons/pl/flexbox.json`, `lessons/pl/01-box-model.json`, + other pl/ modules
|
||||
- `lessons/uk/flexbox.json`, `lessons/uk/01-box-model.json`, + other uk/ modules
|
||||
|
||||
**No new files or deleted files.**
|
||||
|
||||
## 4. Architecture Decisions
|
||||
|
||||
1. **Message-only changes:** Only the `"message"` string within validation objects is modified. The `type`, `value`, and `options` fields remain untouched. This preserves all validation logic.
|
||||
|
||||
2. **No code changes to validator.js:** The validator reads the `message` field as a passthrough string for display. No runtime changes needed.
|
||||
|
||||
3. **Hint style per validation type:**
|
||||
- `property_value` validations → concept question or property hint (since the property and value are tested programmatically, the message should teach the concept, not repeat the answer)
|
||||
- `regex` validations → directional nudge describing the expected pattern conceptually
|
||||
- `contains` / `contains_class` validations → concept question about what to include
|
||||
|
||||
4. **Localization approach:** Each localized message should be a natural translation of the English pedagogical hint, not a word-for-word translation. The hint category (question, nudge, property hint) should match the English version.
|
||||
|
||||
5. **Preserve `<kbd>` tags selectively:** `<kbd>` tags may still be used for property names (e.g., "Check the `<kbd>padding</kbd>` property") but never for complete property-value pairs that reveal the answer.
|
||||
|
||||
## 5. Risks
|
||||
|
||||
| Risk | Likelihood | Mitigation |
|
||||
|------|-----------|------------|
|
||||
| Pedagogical hints are too vague, frustrating learners | Medium | Each hint should name the relevant CSS property or concept — just not the exact value. The task description already provides context. |
|
||||
| Localized translations lose pedagogical intent | Medium | Use consistent hint categories across languages. Review each language for natural phrasing. |
|
||||
| Existing tests assert on specific message text | Low | Check test files for hardcoded message assertions before changing. Adjust tests if needed. |
|
||||
| Formatting inconsistency after bulk edits | Low | Run `npm run format.lessons` after all changes. |
|
||||
|
||||
## 6. Testing Strategy
|
||||
|
||||
1. **Existing test suite:** Run `npm run test` to verify no regressions. The validator tests should pass since validation logic is unchanged.
|
||||
2. **Grep audit:** After changes, grep all lesson files for remaining "Set <kbd>" patterns to confirm none were missed.
|
||||
3. **JSON validity:** Ensure all modified JSON files parse correctly (the format.lessons command will catch syntax errors).
|
||||
4. **Manual spot-check:** Verify a few lessons in the dev server to confirm messages display correctly in the UI.
|
||||
50
specs/004-pedagogical-messages/spec.md
Normal file
50
specs/004-pedagogical-messages/spec.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# fix: validation error messages reveal the solution instead of guiding learning
|
||||
|
||||
**Issue:** [#4](https://git.librete.ch/libretech/code-crispies/issues/4)
|
||||
**Repository:** libretech/code-crispies
|
||||
**Author:** libretech
|
||||
**State:** open
|
||||
**Labels:** none
|
||||
|
||||
## Issue Body
|
||||
|
||||
Pedagogy audit: 88% of exercises reveal the answer in error messages, creating a fail-then-copy loop. Change validation messages from 'Set padding: 1rem' to 'Which property adds space between content and the element edge?' This applies across all modules — start with flexbox, box-model, and colors (the 3 worst offenders).
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Validation error messages in **flexbox**, **box-model**, and **colors** modules must no longer reveal the exact CSS property-value answer
|
||||
2. Replacement messages should use pedagogical hints: concept questions, property-name hints, or directional guidance — never the literal solution
|
||||
3. All remaining English lesson modules with answer-revealing messages must also be rewritten
|
||||
4. Localized variants (ar/, de/, es/, pl/, uk/) of affected modules must be updated with equivalent pedagogical messages in each language
|
||||
5. Existing validations (type, value, options) must remain unchanged — only the `"message"` field is modified
|
||||
6. All existing tests must continue to pass
|
||||
|
||||
## Scope
|
||||
|
||||
### English priority modules (100% answer-revealing):
|
||||
- `lessons/flexbox.json` — 6 messages
|
||||
- `lessons/01-box-model.json` — 10 messages
|
||||
- `lessons/03-colors.json` — 4 messages
|
||||
- `lessons/12-positioning.json` — 5 messages
|
||||
|
||||
### English remaining modules (partial answer-revealing):
|
||||
- `lessons/00-basics.json` — 4 of 26
|
||||
- `lessons/00-basic-selectors.json` — 15 of 18
|
||||
- `lessons/01-advanced-selectors.json` — 8 of 49
|
||||
- `lessons/04-typography.json` — 1 of 9
|
||||
- `lessons/05-units-variables.json` — 3 of 5
|
||||
- `lessons/06-transitions-animations.json` — 8 of 13
|
||||
- `lessons/07-layouts.json` — 8 of 11
|
||||
- `lessons/08-responsive.json` — 8 of 10
|
||||
- `lessons/09-gradients.json` — 3 of 7
|
||||
- `lessons/10-tailwind-basics.json` — 16 of 17
|
||||
- `lessons/11-filters.json` — 4 of 7
|
||||
- `lessons/13-pseudo-elements.json` — 4 of 8
|
||||
- `lessons/grid.json` — 5 of 9
|
||||
|
||||
### Localized variants (each language directory):
|
||||
- `lessons/ar/` — Arabic
|
||||
- `lessons/de/` — German
|
||||
- `lessons/es/` — Spanish
|
||||
- `lessons/pl/` — Polish
|
||||
- `lessons/uk/` — Ukrainian
|
||||
39
specs/004-pedagogical-messages/tasks.md
Normal file
39
specs/004-pedagogical-messages/tasks.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Tasks
|
||||
|
||||
## Phase 1: Preparation
|
||||
- [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)
|
||||
- [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
|
||||
- [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
|
||||
- [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
|
||||
- [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 <kbd>" 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
|
||||
Reference in New Issue
Block a user