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.
This commit is contained in:
2026-01-14 15:39:22 +01:00
parent 617906acb9
commit 1a5c09b750
72 changed files with 2206 additions and 2611 deletions

View File

@@ -1,100 +1,100 @@
{
"$schema": "../../schemas/code-crispies-module-schema.json",
"id": "html-forms-basic",
"title": "HTML Forms",
"description": "Learn to create forms with various input types",
"title": "Formularios HTML",
"description": "Aprende a crear formularios con varios tipos de campos",
"mode": "html",
"difficulty": "beginner",
"lessons": [
{
"id": "form-structure",
"title": "Form Structure",
"description": "Every form needs a <kbd>&lt;form&gt;</kbd> wrapper. Inside, use <kbd>&lt;label&gt;</kbd> to describe inputs and <kbd>&lt;input&gt;</kbd> for user data entry.<br><br>The <kbd>for</kbd> attribute on labels should match the <kbd>id</kbd> on inputs for accessibility.",
"task": "Create a form with:<br>1. A <kbd>&lt;label&gt;</kbd> with the text <code>Name:</code> and <kbd>for=\"name\"</kbd> attribute<br>2. A text <kbd>&lt;input&gt;</kbd> with <kbd>id=\"name\"</kbd> and <kbd>name=\"name\"</kbd> attributes",
"title": "Estructura del formulario",
"description": "Todo formulario necesita un contenedor <kbd>&lt;form&gt;</kbd>. Dentro, usa <kbd>&lt;label&gt;</kbd> para describir campos y <kbd>&lt;input&gt;</kbd> para la entrada de datos.<br><br>El atributo <kbd>for</kbd> en los labels debe coincidir con el <kbd>id</kbd> de los inputs para accesibilidad.",
"task": "Crea un formulario con:<br>1. Un <kbd>&lt;label&gt;</kbd> con el texto <code>Nombre:</code> y el atributo <kbd>for=\"name\"</kbd><br>2. Un <kbd>&lt;input&gt;</kbd> de texto con los atributos <kbd>id=\"name\"</kbd> y <kbd>name=\"name\"</kbd>",
"previewHTML": "",
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 300px; } label { display: block; margin-bottom: 5px; font-weight: 500; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; }",
"sandboxCSS": "",
"initialCode": "",
"solution": "<form>\n <label for=\"name\">Name:</label>\n <input type=\"text\" id=\"name\" name=\"name\">\n</form>",
"solution": "<form>\n <label for=\"name\">Nombre:</label>\n <input type=\"text\" id=\"name\" name=\"name\">\n</form>",
"previewContainer": "preview-area",
"validations": [
{
"type": "element_exists",
"value": "form",
"message": "Wrap everything in a <kbd>&lt;form&gt;</kbd> element"
"message": "Envuelve todo en un elemento <kbd>&lt;form&gt;</kbd>"
},
{
"type": "element_exists",
"value": "label",
"message": "Add a <kbd>&lt;label&gt;</kbd> for your input"
"message": "Añade un <kbd>&lt;label&gt;</kbd> para tu campo"
},
{
"type": "element_exists",
"value": "input",
"message": "Add an <kbd>&lt;input&gt;</kbd> element"
"message": "Añade un elemento <kbd>&lt;input&gt;</kbd>"
},
{
"type": "attribute_value",
"value": { "selector": "label", "attr": "for", "value": null },
"message": "Add a <kbd>for</kbd> attribute to your label"
"message": "Añade un atributo <kbd>for</kbd> a tu label"
},
{
"type": "attribute_value",
"value": { "selector": "input", "attr": "id", "value": null },
"message": "Add an <kbd>id</kbd> attribute to your input"
"message": "Añade un atributo <kbd>id</kbd> a tu campo"
}
]
},
{
"id": "input-types",
"title": "Input Types",
"description": "Different input types provide appropriate keyboards and validation:<br><br><kbd>type=\"text\"</kbd> - General text<br><kbd>type=\"email\"</kbd> - Email with @ validation<br><kbd>type=\"password\"</kbd> - Hidden characters<br><kbd>type=\"number\"</kbd> - Numeric keyboard<br><kbd>type=\"tel\"</kbd> - Phone keyboard",
"task": "Create a login form with two fields:<br>1. An email field: <kbd>&lt;label for=\"email\"&gt;Email:&lt;/label&gt;</kbd> and <kbd>&lt;input type=\"email\" id=\"email\"&gt;</kbd><br>2. A password field: <kbd>&lt;label for=\"password\"&gt;Password:&lt;/label&gt;</kbd> and <kbd>&lt;input type=\"password\" id=\"password\"&gt;</kbd>",
"title": "Tipos de campos",
"description": "Diferentes tipos de campos proporcionan teclados apropiados y validación:<br><br><kbd>type=\"text\"</kbd> - Texto general<br><kbd>type=\"email\"</kbd> - Email con validación @<br><kbd>type=\"password\"</kbd> - Caracteres ocultos<br><kbd>type=\"number\"</kbd> - Teclado numérico<br><kbd>type=\"tel\"</kbd> - Teclado telefónico",
"task": "Crea un formulario de inicio de sesión con dos campos:<br>1. Campo de email: <kbd>&lt;label for=\"email\"&gt;Email:&lt;/label&gt;</kbd> y <kbd>&lt;input type=\"email\" id=\"email\"&gt;</kbd><br>2. Campo de contraseña: <kbd>&lt;label for=\"password\"&gt;Contraseña:&lt;/label&gt;</kbd> y <kbd>&lt;input type=\"password\" id=\"password\"&gt;</kbd>",
"previewHTML": "",
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 300px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-child { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; }",
"sandboxCSS": "",
"initialCode": "<form>\n \n</form>",
"solution": "<form>\n <label for=\"email\">Email:</label>\n <input type=\"email\" id=\"email\" name=\"email\">\n \n <label for=\"password\">Password:</label>\n <input type=\"password\" id=\"password\" name=\"password\">\n</form>",
"solution": "<form>\n <label for=\"email\">Email:</label>\n <input type=\"email\" id=\"email\" name=\"email\">\n \n <label for=\"password\">Contraseña:</label>\n <input type=\"password\" id=\"password\" name=\"password\">\n</form>",
"previewContainer": "preview-area",
"validations": [
{
"type": "element_exists",
"value": "input[type='email']",
"message": "Add an input with type=\"email\""
"message": "Añade un campo con type=\"email\""
},
{
"type": "element_exists",
"value": "input[type='password']",
"message": "Add an input with type=\"password\""
"message": "Añade un campo con type=\"password\""
},
{
"type": "element_count",
"value": { "selector": "label", "min": 2 },
"message": "Add labels for both inputs"
"message": "Añade labels para ambos campos"
}
]
},
{
"id": "submit-button",
"title": "Submit Button",
"description": "Forms need a way to submit data. Use:<br><br><kbd>&lt;button type=\"submit\"&gt;</kbd> - Preferred, flexible content<br><kbd>&lt;input type=\"submit\"&gt;</kbd> - Simple text-only button<br><br>The button text should be action-oriented (e.g., <code>Sign In</code>, 'Register', 'Send').",
"task": "Add a submit button to the form with the text <code>Sign In</code>.",
"title": "Botón de envío",
"description": "Los formularios necesitan una forma de enviar datos. Usa:<br><br><kbd>&lt;button type=\"submit\"&gt;</kbd> - Preferido, contenido flexible<br><kbd>&lt;input type=\"submit\"&gt;</kbd> - Botón de solo texto<br><br>El texto del botón debe estar orientado a la acción (ej. <code>Iniciar Sesión</code>, 'Registrar', 'Enviar').",
"task": "Añade un botón de envío al formulario con el texto <code>Iniciar Sesión</code>.",
"previewHTML": "",
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 300px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-child { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } button { width: 100%; margin-top: 20px; padding: 10px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; } button:hover { background: #1565c0; }",
"sandboxCSS": "",
"initialCode": "<form>\n <label for=\"email\">Email:</label>\n <input type=\"email\" id=\"email\">\n \n <label for=\"password\">Password:</label>\n <input type=\"password\" id=\"password\">\n \n</form>",
"solution": "<form>\n <label for=\"email\">Email:</label>\n <input type=\"email\" id=\"email\">\n \n <label for=\"password\">Password:</label>\n <input type=\"password\" id=\"password\">\n \n <button type=\"submit\">Sign In</button>\n</form>",
"initialCode": "<form>\n <label for=\"email\">Email:</label>\n <input type=\"email\" id=\"email\">\n \n <label for=\"password\">Contraseña:</label>\n <input type=\"password\" id=\"password\">\n \n</form>",
"solution": "<form>\n <label for=\"email\">Email:</label>\n <input type=\"email\" id=\"email\">\n \n <label for=\"password\">Contraseña:</label>\n <input type=\"password\" id=\"password\">\n \n <button type=\"submit\">Iniciar Sesión</button>\n</form>",
"previewContainer": "preview-area",
"validations": [
{
"type": "element_exists",
"value": "button[type='submit'], input[type='submit']",
"message": "Add a submit button to your form"
"message": "Añade un botón de envío a tu formulario"
},
{
"type": "element_text",
"value": { "selector": "button", "text": "Sign In" },
"message": "The button should say <kbd>Sign In</kbd>"
"value": { "selector": "button", "text": "Iniciar Sesión" },
"message": "El botón debe decir <kbd>Iniciar Sesión</kbd>"
}
]
}