Files
code-crispies/lessons/pl/08-responsive.json
Michael Czechowski c560676544 feat: implement #4 — replace answer-revealing validation messages with pedagogical hints
Rewrite ~120 validation error messages across 17 English lesson modules
and their localized variants (ar, de, es, pl, uk) to use concept questions,
property hints, and directional nudges instead of revealing the exact
CSS property-value answers.

Priority modules (flexbox, box-model, colors, positioning) fully rewritten.
All remaining CSS modules updated. Only message strings changed — no
validation logic modifications.
2026-03-28 19:40:28 +01:00

131 lines
6.0 KiB
JSON

{
"$schema": "../../schemas/code-crispies-module-schema.json",
"id": "responsive-design",
"title": "CSS Responsive Design",
"description": "Dostosuj swoje layouty do różnych rozmiarów ekranów używając media queries i technik płynnego designu.",
"difficulty": "intermediate",
"lessons": [
{
"id": "responsive-1",
"title": "Media Queries",
"description": "Poznaj składnię i przypadki użycia CSS media queries do warunkowego stosowania stylów na podstawie cech viewport.<br><br><pre>@media (max-width: 600px) {\n .panel {\n background: lightcoral;\n }\n}</pre>",
"task": "Napisz media query z <kbd>@media (max-width: 600px)</kbd>, która zmienia tło <kbd>.panel</kbd> na <kbd>lightcoral</kbd>.",
"previewHTML": "<div class=\"panel\">Resize the window</div>",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .panel { padding: 1rem; background: lightblue; }",
"sandboxCSS": "",
"codePrefix": "/* Add your media query below */\n",
"initialCode": "",
"codeSuffix": "",
"solution": "@media (max-width: 600px) {\n .panel {\n background: lightcoral;\n }\n}",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "@media\\s*\\(max-width:\\s*600px\\)",
"message": "Użyj <kbd>@media (max-width: 600px)</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "contains",
"value": ".panel",
"message": "Zaadresuj <kbd>.panel</kbd> wewnątrz media query",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "background", "expected": "lightcoral" },
"message": "Sprawdź właściwość <kbd>background</kbd> — jaki kolor potrzebuje panel na małych ekranach?",
"options": { "exact": false }
}
]
},
{
"id": "responsive-2",
"title": "Fluid Type",
"description": "Używaj jednostek względnych jak <kbd>vw</kbd>, aby rozmiary czcionek skalowały się z szerokością viewport.",
"task": "Ustaw <kbd>font-size: 5vw</kbd>, aby skalowała się ze zmianą viewport.",
"previewHTML": "<p class=\"text\">Fluid Typography</p>",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; }",
"sandboxCSS": "",
"codePrefix": "/* Apply fluid font sizing */\n.text {",
"initialCode": "",
"codeSuffix": "}",
"solution": " font-size: 5vw;",
"previewContainer": "preview-area",
"validations": [
{
"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?"
}
]
},
{
"id": "responsive-3",
"title": "Responsive Grid",
"description": "Połącz CSS Grid z <kbd>auto-fit</kbd> lub <kbd>auto-fill</kbd> dla responsywnych układów kolumnowych, które automatycznie dostosowują liczbę kolumn na podstawie dostępnej przestrzeni.",
"task": "Dodaj <kbd>display: grid</kbd>, <kbd>grid-template-columns: repeat(auto-fit, minmax(200px, 1fr))</kbd> i <kbd>gap: 1rem</kbd>.",
"previewHTML": "<section class=\"features\"><article class=\"feature\"><h3>Fast</h3><p>Lightning quick load times</p></article><article class=\"feature\"><h3>Secure</h3><p>Enterprise-grade security</p></article><article class=\"feature\"><h3>Reliable</h3><p>99.9% uptime guaranteed</p></article><article class=\"feature\"><h3>Support</h3><p>24/7 customer service</p></article></section>",
"previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .feature { background: white; padding: 1rem; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .feature h3 { margin: 0 0 8px; color: steelblue; } .feature p { margin: 0; color: #666; font-size: 0.9rem; }",
"sandboxCSS": "",
"codePrefix": ".features {\n ",
"initialCode": "",
"codeSuffix": "\n}",
"solution": "display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1rem;",
"previewContainer": "preview-area",
"validations": [
{
"type": "property_value",
"value": { "property": "display", "expected": "grid" },
"message": "Która wartość <kbd>display</kbd> włącza układ siatkowy?"
},
{
"type": "regex",
"value": "repeat\\(auto-fit,\\s*minmax\\(200px,\\s*1fr\\)\\)",
"message": "Użyj <kbd>repeat(auto-fit, minmax(200px, 1fr))</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
"message": "Sprawdź właściwość <kbd>gap</kbd> — jaki odstęp potrzebują elementy siatki?"
}
]
},
{
"id": "responsive-4",
"title": "Mobile-First",
"description": "Zastosuj podejście mobile-first: pisz bazowe style dla małych ekranów i rozszerzaj dla większych viewport.",
"task": "Napisz media query z <kbd>@media (min-width: 768px)</kbd>, która ustawia szerokość <kbd>.sidebar</kbd> na <kbd>250px</kbd>.",
"previewHTML": "<aside class=\"sidebar\">Sidebar</aside>",
"previewBaseCSS": "body { font-family: sans-serif; padding: 1rem; } .sidebar { background: #c8e6c9; padding: 1rem; }",
"sandboxCSS": "",
"codePrefix": "/* Add mobile-first enhancement */\n",
"initialCode": "",
"codeSuffix": "",
"solution": "@media (min-width: 768px) {\n .sidebar {\n width: 250px;\n }\n}",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "@media\\s*\\(min-width:\\s*768px\\)",
"message": "Użyj <kbd>@media (min-width: 768px)</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "contains",
"value": ".sidebar",
"message": "Zaadresuj <kbd>.sidebar</kbd> w media query",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "width", "expected": "250px" },
"message": "Sprawdź właściwość <kbd>width</kbd> — jaką stałą szerokość potrzebuje sidebar?",
"options": { "exact": false }
}
]
}
]
}