Files
code-crispies/lessons/es/06-transitions-animations.json
Michael Czechowski 1a5c09b750 fix(i18n): sync all lesson translations with English source
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.
2026-01-14 15:39:22 +01:00

146 lines
6.7 KiB
JSON

{
"$schema": "../../schemas/code-crispies-module-schema.json",
"id": "transitions-animations",
"title": "Animaciones CSS",
"description": "Añade interactividad a tu UI mediante transiciones suaves de propiedades y animaciones basadas en keyframes.",
"difficulty": "intermediate",
"lessons": [
{
"id": "transitions-1",
"title": "Transitions",
"description": "Aprende a aplicar <kbd>transition</kbd> a propiedades para cambios suaves en estados.<br><br><pre>transition: property duration;\n/* ej. transition: background-color 0.3s; */</pre>",
"task": "Añade <kbd>transition: background-color 0.3s</kbd> para que el color cambie suavemente al hacer hover.",
"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": "Usa la propiedad <kbd>transition</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "regex",
"value": "transition:\\s*background-color\\s*0\\.3s",
"message": "Establece <kbd>transition: background-color 0.3s</kbd>",
"options": { "caseSensitive": false }
}
]
},
{
"id": "transitions-2",
"title": "Timing Funcs",
"description": "Explora funciones de easing como <kbd>ease</kbd>, <kbd>linear</kbd>, <kbd>ease-in</kbd>, <kbd>ease-out</kbd> para controlar el ritmo de la animación.",
"task": "Establece <kbd>transition-timing-function</kbd> a <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": "Usa <kbd>transition-timing-function</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "transition-timing-function", "expected": "ease-in-out" },
"message": "Establece timing a <kbd>ease-in-out</kbd>"
}
]
},
{
"id": "transitions-3",
"title": "Keyframes",
"description": "Crea animaciones nombradas usando <kbd>@keyframes</kbd> y aplícalas con el atajo <kbd>animation</kbd>.<br><br><pre>@keyframes bounce {\n 50% { transform: translateY(-20px); }\n}\n.ball {\n animation: bounce 1s infinite;\n}</pre>",
"task": "Define un keyframe en <kbd>50%</kbd> con <kbd>transform: translateY(-20px)</kbd> y aplica <kbd>animation: bounce 1s infinite</kbd> a <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": "Define <kbd>@keyframes bounce</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "regex",
"value": "50%.*transform: translateY\\(-20px\\)",
"message": "En <kbd>50%</kbd>, usa <kbd>transform: translateY(-20px)</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "contains",
"value": "animation",
"message": "Usa la propiedad <kbd>animation</kbd> en <kbd>.ball</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "regex",
"value": "animation:.*bounce.*1s.*infinite",
"message": "Aplica <kbd>animation: bounce 1s infinite</kbd>",
"options": { "caseSensitive": false }
}
]
},
{
"id": "transitions-4",
"title": "Animation Properties",
"description": "Ajusta las animaciones con <kbd>animation-delay</kbd>, <kbd>animation-iteration-count</kbd>, <kbd>animation-direction</kbd> y <kbd>animation-fill-mode</kbd>.",
"task": "Aplica la animación <kbd>pulse</kbd> a <kbd>.box</kbd> con <kbd>animation-name: pulse</kbd>, <kbd>animation-duration: 2s</kbd>, <kbd>animation-delay: 1s</kbd>, <kbd>animation-iteration-count: 2</kbd> y <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": "Establece <kbd>animation-name: pulse</kbd>"
},
{
"type": "property_value",
"value": { "property": "animation-duration", "expected": "2s" },
"message": "Establece <kbd>animation-duration: 2s</kbd>"
},
{
"type": "property_value",
"value": { "property": "animation-delay", "expected": "1s" },
"message": "Establece <kbd>animation-delay: 1s</kbd>"
},
{
"type": "property_value",
"value": { "property": "animation-iteration-count", "expected": "2" },
"message": "Establece <kbd>animation-iteration-count: 2</kbd>"
},
{
"type": "property_value",
"value": { "property": "animation-fill-mode", "expected": "forwards" },
"message": "Establece <kbd>animation-fill-mode: forwards</kbd>"
}
]
}
]
}