feat: implement #9 — rewrite colors and box-model task descriptions

Rewrite task text in Colors (4 lessons) and Box Model (8 lessons x 6
locales) to describe visual outcomes instead of giving copy-paste CSS
answers. Colors validations changed from property_value to regex
accepting multiple valid named colors per lesson.
This commit is contained in:
2026-03-28 23:56:55 +01:00
parent 3d6ff645fe
commit 1baff9075c
8 changed files with 81 additions and 77 deletions

View File

@@ -9,7 +9,7 @@
"id": "box-model-1",
"title": "Padding",
"description": "كل عنصر في CSS هو صندوق بأربع طبقات: المحتوى، الحشو (padding)، الحدود، والهامش. <strong>Padding</strong> يخلق مساحة تنفس بين محتواك وحافة الصندوق.<br><br>بدون padding، يضغط النص بشكل محرج على الحدود. Padding يجعل المحتوى قابلاً للقراءة ومتوازناً بصرياً.<br><br><pre>.card {\n padding: 1rem;\n}</pre>",
"task": "بطاقة الملف الشخصي هذه تبدو ضيقة. أضف <kbd>padding: 1rem</kbd> ليكون للنص مجال للتنفس.",
"task": "النص داخل بطاقة الملف الشخصي ملتصق بالحواف. امنحه بعض المساحة الداخلية للتنفس.",
"previewHTML": "<article class=\"card\"><h3>Sarah Chen</h3><p>Frontend Developer</p></article>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .card { background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .card h3 { margin: 0 0 4px; } .card p { margin: 0; color: #666; }",
"sandboxCSS": "",
@@ -30,7 +30,7 @@
"id": "box-model-2",
"title": "Borders",
"description": "الحدود تنشئ حدوداً مرئية حول العناصر. اختصار <kbd>border</kbd> يقبل ثلاث قيم: العرض، النمط، واللون.<br><br>الأنماط الشائعة: <kbd>solid</kbd>، <kbd>dashed</kbd>، <kbd>dotted</kbd>، <kbd>none</kbd>",
"task": "أضف لمسة يسارية خفيفة للبطاقة باستخدام <kbd>border-left: 4px solid steelblue</kbd>.",
"task": "هذه البطاقة تحتاج خطاً ملوناً كلمسة على حافتها اليسرى.",
"previewHTML": "<article class=\"card\"><h3>Sarah Chen</h3><p>Frontend Developer</p></article>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .card { background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); padding: 1rem; } .card h3 { margin: 0 0 4px; } .card p { margin: 0; color: #666; }",
"sandboxCSS": "",
@@ -52,7 +52,7 @@
"id": "box-model-3",
"title": "Margins",
"description": "الهوامش تنشئ مساحة <em>خارج</em> العنصر، تفصله عن جيرانه. بينما يدفع padding المحتوى للداخل، الهوامش تدفع العناصر الأخرى بعيداً.",
"task": "أضف مساحة بين بطاقتي الملف الشخصي هاتين باستخدام <kbd>margin-bottom: 1rem</kbd> على <kbd>.card</kbd>.",
"task": "بطاقتا الملف الشخصي ملتصقتان ببعضهما. أضف مساحة أسفل كل بطاقة للفصل بينهما.",
"previewHTML": "<article class=\"card\"><h3>Sarah Chen</h3><p>Frontend Developer</p></article><article class=\"card\"><h3>Alex Rivera</h3><p>UX Designer</p></article>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .card { background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); padding: 1rem; border-left: 4px solid steelblue; } .card h3 { margin: 0 0 4px; } .card p { margin: 0; color: #666; }",
"sandboxCSS": "",
@@ -73,7 +73,7 @@
"id": "box-model-4",
"title": "Box Sizing",
"description": "افتراضياً، <kbd>width</kbd> يحدد فقط عرض المحتوى. Padding والحدود تُضاف للمجموع. هذا يسبب مشاكل في التخطيط.<br><br><kbd>box-sizing: border-box</kbd> يشمل padding والحدود في العرض، مما يجعل التحجيم متوقعاً. معظم المطورين يطبقون هذا على جميع العناصر.",
"task": "كلا البطاقتين لهما <kbd>width: 200px</kbd>. اليسرى تستخدم التحجيم الافتراضي (content-box)، مما يجعلها أعرض من المتوقع. أصلح البطاقة اليمنى باستخدام <kbd>box-sizing: border-box</kbd>.",
"task": "كلا البطاقتين بنفس العرض، لكن اليسرى تتجاوز لأن الحشو والحدود تُضاف فوق العرض. أصلح البطاقة اليمنى لتشمل الحشو والحدود في حجمها.",
"previewHTML": "<div class=\"demo\"><article class=\"card\">Content-box</article><article class=\"card fix\">Border-box</article></div>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .demo { display: flex; gap: 1rem; } .card { width: 200px; padding: 1rem; border: 4px solid steelblue; background: white; border-radius: 8px; }",
"sandboxCSS": "",
@@ -94,7 +94,7 @@
"id": "box-model-5",
"title": "Padding Shorthand",
"description": "Padding يقبل 1-4 قيم:<br>• قيمة واحدة: جميع الجوانب<br>• قيمتان: عمودي | أفقي<br>• 4 قيم: أعلى | يمين | أسفل | يسار",
"task": "هذا الزر يحتاج مساحة أفقية أكثر من العمودية. اضبط <kbd>padding: 8px 1rem</kbd> (8px أعلى/أسفل، 1rem يسار/يمين).",
"task": "هذا الزر ضيق جداً. امنحه مساحة على الجوانب أكثر من الأعلى والأسفل، باستخدام اختصار القيمتين.",
"previewHTML": "<button class=\"btn\">Follow</button>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .btn { background: steelblue; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; }",
"sandboxCSS": "",
@@ -116,7 +116,7 @@
"id": "box-model-6",
"title": "Margin Shorthand",
"description": "Margin يستخدم نفس نمط الاختصار مثل padding. نمط شائع هو توسيط عناصر الكتلة أفقياً باستخدام <kbd>margin: 0 auto</kbd>.",
"task": "وسّط هذه البطاقة أفقياً. اضبط <kbd>margin: 0 auto</kbd> لحساب هوامش يسار/يمين متساوية تلقائياً.",
"task": "هذه البطاقة ملتصقة باليسار. وسّطها أفقياً باستخدام اختصار الهوامش مع هوامش جانبية تلقائية.",
"previewHTML": "<article class=\"card\"><h3>Sarah Chen</h3><p>Frontend Developer</p></article>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .card { width: 250px; background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); padding: 1rem; border-left: 4px solid steelblue; } .card h3 { margin: 0 0 4px; } .card p { margin: 0; color: #666; }",
"sandboxCSS": "",
@@ -138,7 +138,7 @@
"id": "box-model-7",
"title": "Border Radius",
"description": "على الرغم من أنه ليس جزءاً من نموذج الصندوق الكلاسيكي، <kbd>border-radius</kbd> يُدوّر زوايا صندوق حدود العنصر. استخدم <kbd>50%</kbd> على عنصر مربع لإنشاء دائرة.",
"task": "اجعل صورة الأفاتار دائرية باستخدام <kbd>border-radius: 50%</kbd>.",
"task": "صورة الأفاتار المربعة يجب أن تظهر كدائرة مثالية.",
"previewHTML": "<article class=\"card\"><img class=\"avatar\" src=\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='35' r='25' fill='%23666'/%3E%3Ccircle cx='50' cy='90' r='40' fill='%23666'/%3E%3C/svg%3E\" alt=\"Avatar\"><h3>Sarah Chen</h3><p>Frontend Developer</p></article>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .card { background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); padding: 1rem; text-align: center; } .avatar { width: 80px; height: 80px; background: #ddd; margin-bottom: 8px; } .card h3 { margin: 0 0 4px; } .card p { margin: 0; color: #666; }",
"sandboxCSS": "",
@@ -159,7 +159,7 @@
"id": "box-model-8",
"title": "Complete Card",
"description": "لنجمع كل شيء معاً. بطاقة الإشعار هذه تحتاج تنسيقاً لتبدو احترافية.",
"task": "نسّق الإشعار: أضف <kbd>padding: 1rem</kbd>، <kbd>border-left: 4px solid coral</kbd>، و<kbd>border-radius: 4px</kbd>.",
"task": "هذا الإشعار يحتاج ثلاثة أشياء: مساحة داخلية حتى لا يكون النص مزدحماً، لمسة ملونة على الحافة اليسرى، وزوايا مستديرة قليلاً.",
"previewHTML": "<div class=\"alert\"><strong>New message</strong><p>You have 3 unread notifications</p></div>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .alert { background: seashell; } .alert strong { color: coral; } .alert p { margin: 4px 0 0; color: #666; }",
"sandboxCSS": "",