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.
This commit is contained in:
2026-03-28 19:40:28 +01:00
parent 782e87705c
commit c560676544
50 changed files with 434 additions and 403 deletions

View File

@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
"message": "Añade <kbd>color: coral;</kbd>"
"message": "¿Qué propiedad controla el color del texto?"
}
]
},
@@ -43,12 +43,12 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "lavender" },
"message": "ade <kbd>background: lavender;</kbd>"
"message": "Revisa la propiedad <kbd>background</kbd>"
},
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
"message": "Añade <kbd>padding: 1rem;</kbd>"
"message": "La tarjeta necesita espacio dentro de sus bordes"
}
]
},
@@ -74,7 +74,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "steelblue" },
"message": "Establece <kbd>color: steelblue</kbd>"
"message": "¿Qué propiedad cambia el color del texto?"
}
]
},
@@ -100,7 +100,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "coral" },
"message": "Establece <kbd>color: coral</kbd>"
"message": "¿Qué valor da un color cálido, rojo-anaranjado?"
}
]
},
@@ -126,7 +126,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "tomato" },
"message": "Establece <kbd>background: tomato</kbd>"
"message": "El badge necesita un fondo rojo brillante"
}
]
},
@@ -152,7 +152,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "steelblue" },
"message": "Establece <kbd>background: steelblue</kbd>"
"message": "¿Qué propiedad establece el color de relleno del botón?"
}
]
},
@@ -178,7 +178,7 @@
{
"type": "property_value",
"value": { "property": "text-decoration", "expected": "none" },
"message": "Establece <kbd>text-decoration: none</kbd>"
"message": "¿Qué propiedad controla el subrayado de los enlaces?"
}
]
},
@@ -199,7 +199,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "steelblue" },
"message": "Establece <kbd>color: steelblue</kbd>"
"message": "Revisa la propiedad <kbd>color</kbd>"
}
]
},
@@ -225,7 +225,7 @@
{
"type": "property_value",
"value": { "property": "color", "expected": "white" },
"message": "Establece <kbd>color: white</kbd>"
"message": "Los enlaces necesitan destacar sobre el fondo azul"
}
]
},
@@ -251,7 +251,7 @@
{
"type": "property_value",
"value": { "property": "font-size", "expected": "0.9rem" },
"message": "Establece <kbd>font-size: 0.9rem</kbd>"
"message": "Revisa la propiedad <kbd>font-size</kbd> — el texto debería ser ligeramente más pequeño"
}
]
}

View File

@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
"message": "Establece <kbd>padding: 1rem</kbd>"
"message": "¿Qué propiedad añade espacio entre el contenido de un elemento y su borde?"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+steelblue",
"message": "Establece <kbd>border-left: 4px solid steelblue</kbd>",
"message": "Usa el atajo <kbd>border-left</kbd> con valores de ancho, estilo y color",
"options": { "caseSensitive": false }
}
]
@@ -65,7 +65,7 @@
{
"type": "property_value",
"value": { "property": "margin-bottom", "expected": "1rem" },
"message": "Establece <kbd>margin-bottom: 1rem</kbd>"
"message": "¿Qué propiedad crea espacio debajo de un elemento, separándolo de sus vecinos?"
}
]
},
@@ -86,7 +86,7 @@
{
"type": "property_value",
"value": { "property": "box-sizing", "expected": "border-box" },
"message": "Establece <kbd>box-sizing: border-box</kbd>"
"message": "¿Qué valor de <kbd>box-sizing</kbd> incluye padding y borde en el ancho total del elemento?"
}
]
},
@@ -107,7 +107,7 @@
{
"type": "regex",
"value": "padding:\\s*8px\\s+1rem",
"message": "Establece <kbd>padding: 8px 1rem</kbd>",
"message": "Usa el atajo <kbd>padding</kbd> con dos valores: vertical y luego horizontal",
"options": { "caseSensitive": false }
}
]
@@ -129,7 +129,7 @@
{
"type": "regex",
"value": "margin:\\s*0\\s+auto",
"message": "Establece <kbd>margin: 0 auto</kbd>",
"message": "Usa <kbd>margin</kbd> con una palabra clave que calcula automáticamente espaciado igual a izquierda y derecha",
"options": { "caseSensitive": false }
}
]
@@ -151,7 +151,7 @@
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "50%" },
"message": "Establece <kbd>border-radius: 50%</kbd>"
"message": "¿Qué porcentaje de <kbd>border-radius</kbd> crea un círculo perfecto a partir de un elemento cuadrado?"
}
]
},
@@ -172,18 +172,18 @@
{
"type": "property_value",
"value": { "property": "padding", "expected": "1rem" },
"message": "Establece <kbd>padding: 1rem</kbd>"
"message": "El elemento necesita espacio interior"
},
{
"type": "regex",
"value": "border-left:\\s*4px\\s+solid\\s+coral",
"message": "Establece <kbd>border-left: 4px solid coral</kbd>",
"message": "Añade un acento de borde izquierdo usando el atajo <kbd>border-left</kbd>",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "border-radius", "expected": "4px" },
"message": "Establece <kbd>border-radius: 4px</kbd>"
"message": "Redondea las esquinas ligeramente con <kbd>border-radius</kbd>"
}
]
}

View File

@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "max-width", "expected": "40rem" },
"message": "Establece <kbd>max-width: 40rem</kbd>"
"message": "¿Qué propiedad limita el ancho de un elemento? Prueba un valor en <kbd>rem</kbd> para una longitud de línea legible."
}
]
},
@@ -49,7 +49,7 @@
{
"type": "contains",
"value": "steelblue",
"message": "Establece el valor a <kbd>steelblue</kbd>",
"message": "Asigna el valor <kbd>steelblue</kbd> a la variable",
"options": { "caseSensitive": false }
}
]
@@ -71,7 +71,7 @@
{
"type": "regex",
"value": "width:\\s*calc\\(\\s*100%\\s*-\\s*200px\\s*\\)",
"message": "Establece <kbd>width: calc(100% - 200px)</kbd>",
"message": "Usa <kbd>calc()</kbd> para restar el ancho fijo de la barra lateral del ancho total del contenedor.",
"options": { "caseSensitive": false }
}
]
@@ -93,7 +93,7 @@
{
"type": "property_value",
"value": { "property": "min-height", "expected": "100vh" },
"message": "Establece <kbd>min-height: 100vh</kbd>"
"message": "¿Qué propiedad asegura una altura mínima? Usa una unidad de viewport para cobertura de pantalla completa."
}
]
}

View File

@@ -28,7 +28,7 @@
{
"type": "regex",
"value": "transition:\\s*background-color\\s*0\\.3s",
"message": "Establece <kbd>transition: background-color 0.3s</kbd>",
"message": "Especifica qué propiedad transicionar y cuánto debe durar.",
"options": { "caseSensitive": false }
}
]
@@ -56,7 +56,7 @@
{
"type": "property_value",
"value": { "property": "transition-timing-function", "expected": "ease-in-out" },
"message": "Establece timing a <kbd>ease-in-out</kbd>"
"message": "¿Qué palabra clave de easing empieza lento, acelera, y luego desacelera de nuevo?"
}
]
},
@@ -95,7 +95,7 @@
{
"type": "regex",
"value": "animation:.*bounce.*1s.*infinite",
"message": "Aplica <kbd>animation: bounce 1s infinite</kbd>",
"message": "Usa el atajo <kbd>animation</kbd>: nombre, duración y número de repeticiones.",
"options": { "caseSensitive": false }
}
]
@@ -117,27 +117,27 @@
{
"type": "property_value",
"value": { "property": "animation-name", "expected": "pulse" },
"message": "Establece <kbd>animation-name: pulse</kbd>"
"message": "¿Qué propiedad vincula un elemento a una regla <kbd>@keyframes</kbd> nombrada?"
},
{
"type": "property_value",
"value": { "property": "animation-duration", "expected": "2s" },
"message": "Establece <kbd>animation-duration: 2s</kbd>"
"message": "¿Cuánto debe durar un ciclo completo de la animación?"
},
{
"type": "property_value",
"value": { "property": "animation-delay", "expected": "1s" },
"message": "Establece <kbd>animation-delay: 1s</kbd>"
"message": "¿Qué propiedad hace que la animación espere antes de comenzar?"
},
{
"type": "property_value",
"value": { "property": "animation-iteration-count", "expected": "2" },
"message": "Establece <kbd>animation-iteration-count: 2</kbd>"
"message": "¿Qué propiedad controla cuántas veces se repite la animación?"
},
{
"type": "property_value",
"value": { "property": "animation-fill-mode", "expected": "forwards" },
"message": "Establece <kbd>animation-fill-mode: forwards</kbd>"
"message": "¿Qué propiedad mantiene el elemento con los estilos de su último keyframe después de que termina la animación?"
}
]
}

View File

@@ -22,7 +22,7 @@
{
"type": "regex",
"value": "@media\\s*\\(max-width:\\s*600px\\)",
"message": "Usa <kbd>@media (max-width: 600px)</kbd>",
"message": "Empieza con una regla <kbd>@media</kbd> — ¿qué condición apunta a pantallas de 600px de ancho o menos?",
"options": { "caseSensitive": false }
},
{
@@ -34,7 +34,7 @@
{
"type": "property_value",
"value": { "property": "background", "expected": "lightcoral" },
"message": "Establece <kbd>background: lightcoral</kbd>",
"message": "¿Qué propiedad cambia el color de fondo del elemento?",
"options": { "exact": false }
}
]
@@ -56,7 +56,7 @@
{
"type": "property_value",
"value": { "property": "font-size", "expected": "5vw" },
"message": "Establece <kbd>font-size: 5vw</kbd>"
"message": "¿Qué unidad CSS escala en relación al ancho del viewport?"
}
]
},
@@ -77,18 +77,18 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "grid" },
"message": "Establece <kbd>display: grid</kbd>"
"message": "¿Qué modo de display permite definir filas y columnas?"
},
{
"type": "regex",
"value": "repeat\\(auto-fit,\\s*minmax\\(200px,\\s*1fr\\)\\)",
"message": "Usa <kbd>repeat(auto-fit, minmax(200px, 1fr))</kbd>",
"message": "Prueba <kbd>repeat()</kbd> con <kbd>auto-fit</kbd> y <kbd>minmax()</kbd> — ¿qué tamaños mínimo y máximo crean columnas flexibles?",
"options": { "caseSensitive": false }
},
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
"message": "Establece <kbd>gap: 1rem</kbd>"
"message": "¿Qué propiedad añade espacio entre los elementos del grid?"
}
]
},
@@ -109,7 +109,7 @@
{
"type": "regex",
"value": "@media\\s*\\(min-width:\\s*768px\\)",
"message": "Usa <kbd>@media (min-width: 768px)</kbd>",
"message": "¿Qué condición <kbd>@media</kbd> aplica estilos cuando el viewport tiene al menos 768px de ancho?",
"options": { "caseSensitive": false }
},
{
@@ -121,7 +121,7 @@
{
"type": "property_value",
"value": { "property": "width", "expected": "250px" },
"message": "Establece <kbd>width: 250px</kbd>",
"message": "¿Qué propiedad controla el ancho de la barra lateral en pantallas más grandes?",
"options": { "exact": false }
}
]

View File

@@ -22,7 +22,7 @@
{
"type": "property_value",
"value": { "property": "display", "expected": "flex" },
"message": "Establece <kbd>display: flex</kbd>"
"message": "¿Qué valor de display convierte un elemento en un contenedor de caja flexible?"
}
]
},
@@ -43,7 +43,7 @@
{
"type": "property_value",
"value": { "property": "gap", "expected": "1rem" },
"message": "Establece <kbd>gap: 1rem</kbd>"
"message": "¿Qué propiedad crea espaciado entre elementos flex sin usar márgenes?"
}
]
},
@@ -64,7 +64,7 @@
{
"type": "property_value",
"value": { "property": "justify-content", "expected": "space-between" },
"message": "Establece <kbd>justify-content: space-between</kbd>"
"message": "¿Qué valor de <kbd>justify-content</kbd> empuja el primer y último elemento a los extremos opuestos?"
}
]
},
@@ -85,7 +85,7 @@
{
"type": "property_value",
"value": { "property": "align-items", "expected": "center" },
"message": "Establece <kbd>align-items: center</kbd>"
"message": "¿Qué propiedad alinea los elementos flex a lo largo del eje transversal?"
}
]
},
@@ -106,7 +106,7 @@
{
"type": "property_value",
"value": { "property": "flex-wrap", "expected": "wrap" },
"message": "Establece <kbd>flex-wrap: wrap</kbd>"
"message": "¿Qué propiedad permite que los elementos flex fluyan a múltiples líneas?"
}
]
},
@@ -127,7 +127,7 @@
{
"type": "property_value",
"value": { "property": "flex", "expected": "1" },
"message": "Establece <kbd>flex: 1</kbd>"
"message": "¿Qué propiedad hace que un elemento flex crezca para llenar el espacio restante?"
}
]
}