Synchronizes 72 lesson files across 5 languages (de, pl, es, ar, uk) to match the English source. This ensures code, solutions, and validations are identical while only title, description, task, and message fields are translated. Changes include: - Box model lessons (01-box-model.json) - Units and variables (05-units-variables.json) - Transitions and animations (06-transitions-animations.json) - Responsive design (08-responsive.json) - HTML elements (20-html-elements.json) - HTML forms basic and validation (21, 22) - HTML details/summary, progress/meter (23, 24) - HTML datalist, dialog, fieldset (25, 27, 28) - HTML tables and SVG (30, 32) - HTML marquee (31) - Welcome module (00-welcome.json) Fixes validation inconsistencies and removes extra content that exceeded English source. German translations were largely correct; Polish, Spanish, Arabic, and Ukrainian required full translations.
146 lines
6.9 KiB
JSON
146 lines
6.9 KiB
JSON
{
|
|
"$schema": "../../schemas/code-crispies-module-schema.json",
|
|
"id": "transitions-animations",
|
|
"title": "حركات CSS",
|
|
"description": "أضف التفاعل لواجهتك من خلال انتقالات الخصائص السلسة والحركات المبنية على keyframes.",
|
|
"difficulty": "intermediate",
|
|
"lessons": [
|
|
{
|
|
"id": "transitions-1",
|
|
"title": "Transitions",
|
|
"description": "تعلم كيفية تطبيق <kbd>transition</kbd> على الخصائص للتغييرات السلسة عند تغيير الحالة.<br><br><pre>transition: property duration;\n/* مثال: transition: background-color 0.3s; */</pre>",
|
|
"task": "أضف <kbd>transition: background-color 0.3s</kbd> ليتغير اللون بسلاسة عند التمرير.",
|
|
"previewHTML": "<button class=\"btn\">Hover Me</button>",
|
|
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .btn { background: black; color: white; padding: 0.5rem 1rem; border: none; cursor: pointer; } .btn:hover { background: white; color: black; }",
|
|
"sandboxCSS": "",
|
|
"codePrefix": "/* Add transition */\n.btn {",
|
|
"initialCode": "",
|
|
"codeSuffix": "}",
|
|
"solution": " transition: background-color 0.3s;",
|
|
"previewContainer": "preview-area",
|
|
"validations": [
|
|
{
|
|
"type": "contains",
|
|
"value": "transition",
|
|
"message": "استخدم خاصية <kbd>transition</kbd>",
|
|
"options": { "caseSensitive": false }
|
|
},
|
|
{
|
|
"type": "regex",
|
|
"value": "transition:\\s*background-color\\s*0\\.3s",
|
|
"message": "اضبط <kbd>transition: background-color 0.3s</kbd>",
|
|
"options": { "caseSensitive": false }
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "transitions-2",
|
|
"title": "Timing Funcs",
|
|
"description": "استكشف دوال التسهيل مثل <kbd>ease</kbd>، <kbd>linear</kbd>، <kbd>ease-in</kbd>، <kbd>ease-out</kbd> للتحكم في إيقاع الحركة.",
|
|
"task": "اضبط <kbd>transition-timing-function</kbd> على <kbd>ease-in-out</kbd>.",
|
|
"previewHTML": "<button class=\"btn\">Timing</button>",
|
|
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .btn { background: navy; color: gold; padding: 0.5rem 1rem; border: none; cursor: pointer; transition: all 0.5s; } .btn:hover { background: gold; color: navy; transform: scale(1.1); }",
|
|
"sandboxCSS": "",
|
|
"codePrefix": "/* Set timing function */\n.btn {",
|
|
"initialCode": "",
|
|
"codeSuffix": "}",
|
|
"solution": " transition-timing-function: ease-in-out;",
|
|
"previewContainer": "preview-area",
|
|
"validations": [
|
|
{
|
|
"type": "contains",
|
|
"value": "transition-timing-function",
|
|
"message": "استخدم <kbd>transition-timing-function</kbd>",
|
|
"options": { "caseSensitive": false }
|
|
},
|
|
{
|
|
"type": "property_value",
|
|
"value": { "property": "transition-timing-function", "expected": "ease-in-out" },
|
|
"message": "اضبط التوقيت على <kbd>ease-in-out</kbd>"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "transitions-3",
|
|
"title": "Keyframes",
|
|
"description": "أنشئ حركات مسماة باستخدام <kbd>@keyframes</kbd> وطبّقها عبر اختصار <kbd>animation</kbd>.<br><br><pre>@keyframes bounce {\n 50% { transform: translateY(-20px); }\n}\n.ball {\n animation: bounce 1s infinite;\n}</pre>",
|
|
"task": "عرّف keyframe عند <kbd>50%</kbd> مع <kbd>transform: translateY(-20px)</kbd> وطبّق <kbd>animation: bounce 1s infinite</kbd> على <kbd>.ball</kbd>.",
|
|
"previewHTML": "<div class=\"ball\"></div>",
|
|
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .ball { width: 50px; height: 50px; background: crimson; border-radius: 50%; margin: 2rem auto; }",
|
|
"sandboxCSS": "",
|
|
"codePrefix": "/* Define keyframes and apply animation */\n@keyframes bounce {",
|
|
"initialCode": "",
|
|
"codeSuffix": "}\n.ball { }",
|
|
"solution": " 50% { transform: translateY(-20px); }\n}\n.ball {\n animation: bounce 1s infinite;",
|
|
"previewContainer": "preview-area",
|
|
"validations": [
|
|
{
|
|
"type": "contains",
|
|
"value": "@keyframes bounce",
|
|
"message": "عرّف <kbd>@keyframes bounce</kbd>",
|
|
"options": { "caseSensitive": false }
|
|
},
|
|
{
|
|
"type": "regex",
|
|
"value": "50%.*transform: translateY\\(-20px\\)",
|
|
"message": "عند <kbd>50%</kbd>، استخدم <kbd>transform: translateY(-20px)</kbd>",
|
|
"options": { "caseSensitive": false }
|
|
},
|
|
{
|
|
"type": "contains",
|
|
"value": "animation",
|
|
"message": "استخدم خاصية <kbd>animation</kbd> على <kbd>.ball</kbd>",
|
|
"options": { "caseSensitive": false }
|
|
},
|
|
{
|
|
"type": "regex",
|
|
"value": "animation:.*bounce.*1s.*infinite",
|
|
"message": "طبّق <kbd>animation: bounce 1s infinite</kbd>",
|
|
"options": { "caseSensitive": false }
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "transitions-4",
|
|
"title": "Animation Properties",
|
|
"description": "اضبط الحركات بـ <kbd>animation-delay</kbd>، <kbd>animation-iteration-count</kbd>، <kbd>animation-direction</kbd>، و <kbd>animation-fill-mode</kbd>.",
|
|
"task": "طبّق حركة <kbd>pulse</kbd> على <kbd>.box</kbd> مع <kbd>animation-name: pulse</kbd>، <kbd>animation-duration: 2s</kbd>، <kbd>animation-delay: 1s</kbd>، <kbd>animation-iteration-count: 2</kbd>، و <kbd>animation-fill-mode: forwards</kbd>.",
|
|
"previewHTML": "<div class=\"box\">Pulse</div>",
|
|
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .box { width: 100px; height: 100px; background: black; color: white; display: flex; align-items: center; justify-content: center; margin: 2rem auto; } @keyframes pulse { 0% { background: black; color: white; transform: scale(1); } 50% { background: white; color: black; transform: scale(1.2); } 100% { background: limegreen; color: black; transform: scale(1); } }",
|
|
"sandboxCSS": "",
|
|
"codePrefix": "/* Apply animation properties */\n.box {",
|
|
"initialCode": "",
|
|
"codeSuffix": "}",
|
|
"solution": " animation-name: pulse;\n animation-duration: 2s;\n animation-delay: 1s;\n animation-iteration-count: 2;\n animation-fill-mode: forwards;",
|
|
"previewContainer": "preview-area",
|
|
"validations": [
|
|
{
|
|
"type": "property_value",
|
|
"value": { "property": "animation-name", "expected": "pulse" },
|
|
"message": "اضبط <kbd>animation-name: pulse</kbd>"
|
|
},
|
|
{
|
|
"type": "property_value",
|
|
"value": { "property": "animation-duration", "expected": "2s" },
|
|
"message": "اضبط <kbd>animation-duration: 2s</kbd>"
|
|
},
|
|
{
|
|
"type": "property_value",
|
|
"value": { "property": "animation-delay", "expected": "1s" },
|
|
"message": "اضبط <kbd>animation-delay: 1s</kbd>"
|
|
},
|
|
{
|
|
"type": "property_value",
|
|
"value": { "property": "animation-iteration-count", "expected": "2" },
|
|
"message": "اضبط <kbd>animation-iteration-count: 2</kbd>"
|
|
},
|
|
{
|
|
"type": "property_value",
|
|
"value": { "property": "animation-fill-mode", "expected": "forwards" },
|
|
"message": "اضبط <kbd>animation-fill-mode: forwards</kbd>"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|