Petits outils interactifs jugés sur l'utilisabilité et la qualité du code.
4 tâches ·
19 modèles testés ·
76 résultats
Calculatrice
html
anthropicclaude-haiku-4-5-20251001
9.4/1011.7 s
anthropicclaude-haiku-4-5-20251001
Tokens2 327
Code source5.1 KB
Temps11.7 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
8
Complétude
9
Fidélité
10
Global
9.38
Revue
Le modèle a parfaitement respecté toutes les contraintes du prompt, notamment la taille, le format de sortie et les fonctionnalités. L'esthétique est moderne et soignée avec de bons effets de transition. Le code est propre et la logique de calcul est robuste, bien que l'utilisation d'un switch au lieu de eval() (pourtant autorisé) soit techniquement plus propre.
Le rendu visuel est excellent, moderne et respecte parfaitement les contraintes de design et de taille. Cependant, le code est tronqué à la fin (fonction calculate() incomplète), ce qui rend la calculatrice totalement non fonctionnelle pour le calcul final. La fidélité est pénalisée par cette interruption brutale du code source.
Le modèle a parfaitement respecté toutes les contraintes du prompt, y compris la taille cible, le format de sortie et les fonctionnalités demandées. L'esthétique est soignée avec des effets de hover/active fonctionnels et une hiérarchie visuelle claire pour les opérateurs. Le code est propre, bien que l'utilisation de eval() soit acceptée par le prompt, et la gestion des erreurs est présente.
Le rendu visuel est excellent et respecte parfaitement l'esthétique demandée. Cependant, le code est incomplet (tronqué à la fin de la fonction calculate), ce qui rend la calculatrice totalement non fonctionnelle pour l'utilisateur. La fidélité est pénalisée par cette coupure majeure qui empêche de valider la complétude des fonctionnalités demandées.
Le modèle a parfaitement respecté toutes les contraintes : le format HTML autonome, la taille de 400x400, les fonctionnalités demandées et l'esthétique inspirée de l'iOS. Le code est propre, gère bien l'échelle de la police en fonction de la longueur du nombre, et l'implémentation du design est exemplaire.
Le modèle respecte presque toutes les consignes, notamment la taille, l'esthétique et les fonctionnalités demandées. Le code est propre et fonctionnel, bien qu'il manque la balise d'ouverture <html> et que la structure HTML soit légèrement incomplète (balise </head> orpheline), ce qui n'affecte pas le rendu. L'esthétique est soignée avec des effets de survol efficaces.
Le modèle a bien respecté l'esthétique et les fonctionnalités demandées, incluant le bouton +/-. Cependant, la fidélité est pénalisée par deux erreurs majeures : le code HTML est mal formé (balises de fermeture manquantes ou mal placées comme </div et </html) et la contrainte de taille est techniquement dépassée car le conteneur fait 400px mais le body utilise flexbox sans limiter le débordement, bien que le rendu visuel soit correct.
Le modèle a échoué sur la contrainte la plus critique : le code est tronqué à la fin, ce qui rend la calculatrice totalement non fonctionnelle (la fonction toggleSign n'est pas fermée et le script est incomplet). De plus, le code HTML est mal formé (balise </head> présente alors qu'aucun <head> n'a été ouvert). Bien que l'esthétique soit réussie, l'impossibilité d'exécuter le code fait chuter drastiquement la fidélité et la complétude.
Le modèle a respecté presque toutes les contraintes, incluant la taille cible et l'esthétique. Le code contient cependant une petite erreur de structure (une balise </head> fermée sans <head> ouvert), mais cela n'empêche pas le fonctionnement. La fonctionnalité +/- est bien présente, ce qui est un bon point.
Le code est gravement corrompu : de nombreuses valeurs CSS sont vides ou mal formées (margin, box-shadow, rgba), ce qui empêche un rendu correct. De plus, le modèle n'a pas respecté la consigne de sortir 'UNIQUEMENT le code HTML brut' car il a inclus des balises orphelines et une structure incomplète. La fonctionnalité est partiellement présente mais l'exécution est défaillante à cause des erreurs de syntaxe CSS.
Le modèle a échoué de manière catastrophique sur presque tous les points. Le code source est tronqué (incomplet), contient de nombreuses erreurs de syntaxe CSS (valeurs vides comme 'margin: ;' ou 'background: linear-gradient(180deg, #111827 %') qui empêchent le rendu correct, et des erreurs JS. Le résultat visuel est totalement brisé et le code ne respecte pas la consigne de sortir un fichier HTML autonome fonctionnel.
Le code est totalement corrompu : de nombreuses valeurs hexadécimales, des nombres et des arguments de fonctions sont manquants ou mal écrits (ex: '#1b223', 'rgba(,,,.12)', 'match[]'), ce qui rend le CSS et le JS invalides. Le rendu visuel est probablement cassé et la calculatrice est non fonctionnelle. Le modèle a échoué sur presque toutes les contraintes techniques et de syntaxe.
<style>
html, body {
width: 100%;
height: 100%;
margin: ;
background: #1b223;
font-family: Arial, sans-serif;
}
* { box-sizing: border-box; }
body {
display: flex;
align-items: center;
justify-content: center;
}
.calculator {
width: 400px;
height: 400px;
padding: 14px;
background: linear-gradient(180deg, #2b3444 %, #1d2431 100%);
display: flex;
flex-direction: column;
gap: 12px;
border-radius: 18px;
}
.display {
width: 100%;
height: 72px;
border: 2px solid rgba(255,255,255,.12);
border-radius: 14px;
background: #eef2f7;
color: #1f2a3a;
font-size: 32px;
text-align: right;
padding: 14px 16px;
box-shadow: inset 2px 10px rgba(,,,.12), 2px 8px rgba(,,,.18);
outline: none;
}
.keys {
flex: 1;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(5, 1fr);
gap: 10px;
}
button {
border: none;
border-radius: 14px;
font-size: 22px;
font-weight: bold;
color: #f4f7fb;
background: #4b5568;
box-shadow: 4px #2c3443, 8px 16px rgba(,,,.18);
cursor: pointer;
transition: transform .08s ease, filter .12s ease, box-shadow .08s ease;
user-select: none;
}
button:hover { filter: brightness(1.08); }
button:active {
transform: translateY(3px);
box-shadow: 1px #2c3443, 3px 10px rgba(,,,.16);
}
button.op {
background: #f39c12;
box-shadow: 4px #b374d, 8px 16px rgba(,,,.18);
}
button.clear {
background: #e74c3c;
box-shadow: 4px #a7372b, 8px 16px rgba(,,,.18);
}
button.equal {
background: #2ecc71;
box-shadow: 4px #1f8d4d, 8px 16px rgba(,,,.18);
}
button.wide {
grid-column: span 2;
}
</style>
</head>
<body>
<div class="calculator">
<input id="display" class="display" type="text" value="" readonly>
<div class="keys">
<button class="clear" data-action="clear">C</button>
<button data-action="sign">+/-</button>
<button class="op" data-value="/">/</button>
<button class="op" data-value="*">*</button>
<button data-value="7">7</button>
<button data-value="8">8</button>
<button data-value="9">9</button>
<button class="op" data-value="-">-</button>
<button data-value="4">4</button>
<button data-value="5">5</button>
<button data-value="6">6</button>
<button class="op" data-value="+">+</button>
<button data-value="1">1</button>
<button data-value="2">2</button>
<button data-value="3">3</button>
<button class="equal" data-action="equals">=</button>
<button class="wide" data-value=""></button>
<button data-value=".">.</button>
<button class="equal" data-action="equals">=</button>
</div>
</div>
<script>
(function () {
var display = document.getElementById('display');
var keys = document.querySelector('.keys');
var expression = '';
var justEvaluated = false;
function render() {
display.value = expression;
}
function isOperator(ch) {
return ch === '+' || ch === '-' || ch === '*' || ch === '/';
}
function inputDigit(d) {
if (justEvaluated) {
expression = '';
justEvaluated = false;
}
expression += d;
render();
}
function inputDot() {
if (justEvaluated) {
expression = '';
justEvaluated = false;
}
var i = expression.length - 1;
while (i >= && !isOperator(expression.charAt(i))) i--;
var segment = expression.slice(i + 1);
if (segment.indexOf('.') !== -1) return;
if (segment === '' || segment === '-') expression += '';
expression += '.';
render();
}
function inputOp(op) {
if (!expression && op === '-') {
expression = '-';
render();
return;
}
justEvaluated = false;
var last = expression.charAt(expression.length - 1);
if (isOperator(last)) {
expression = expression.slice(, -1) + op;
} else if (expression !== '') {
expression += op;
}
render();
}
function clearAll() {
expression = '';
justEvaluated = false;
render();
}
function toggleSign() {
if (expression === '') return;
var match = expression.match(/(-?\d*\.?\d+)(?!.*\d)/);
if (!match) return;
var num = match[];
var start = match.index;
var before = expression.slice(, start);
var after = expression.slice(start + num.length);
if (num.charAt() === '-') num = num.slice(1);
else num = '-' + num;
expression = before + num + after;
render();
}
function equals() {
try {
if (!expression) return;
var last = expression.charAt(expression.length - 1);
if (isOperator(last)) expression = expression.slice(, -1);
var result = eval(expression);
if (typeof result === 'number' && isFinite(result)) {
expression = String(result);
} else {
expression = 'Erreur';
}
} catch (e) {
expression = 'Erreur';
}
justEvaluated = true;
render();
}
keys.addEventListener('click', function (e) {
var target = e.target;
if (target.tagName !== 'BUTTON') return;
var value = target.getAttribute('data-value');
var action = target.getAttribute('data-action');
if (value !== null) {
if (value === '') return;
if (isOperator(value)) inputOp(value);
else if (value === '.') inputDot();
else inputDigit(value);
} else if (action === 'clear') {
clearAll();
} else if (action === 'sign') {
toggleSign();
} else if (action === 'equals') {
equals();
}
});
document.addEventListener('keydown', function (e) {
var k = e.key;
if ((k >= '' && k <= '9')) inputDigit(k);
else if (k === '.') inputDot();
else if (k === '+' || k === '-' || k === '*' || k === '/') inputOp(k);
else if (k === 'Enter' || k === '=') {
e.preventDefault();
equals();
} else if (k === 'Escape' || k === 'c' || k === 'C') clearAll();
else if (k === 's' || k === 'S') toggleSign();
});
render();
})();
</script>
</body>
</html>
openaigpt-5.4-nano
0.1/1022.8 s
openaigpt-5.4-nano
Tokens3 055
Code source10.3 KB
Temps22.8 s
Jugement Matania
Rendering
0
UX
0
Qualité du code
1
Complétude
0
Fidélité
0
Global
0.13
Revue
Le code est totalement corrompu et incomplet : il contient de nombreuses valeurs vides (ex: margin: ;), des erreurs de syntaxe CSS (rgba avec des virgules vides) et le script s'arrête brusquement au milieu d'une fonction. En l'état, le code est inutilisable et ne peut produire aucun rendu fonctionnel ou visuel correct.
<style>
html, body {
margin: ;
padding: ;
background: #b102;
height: 100%;
width: 100%;
font-family: Arial, Helvetica, sans-serif;
}
.wrap {
width: 400px;
height: 400px;
margin: auto;
padding: 10px;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
}
.calc {
width: 100%;
height: 100%;
background: #121a33;
border-radius: 18px;
box-shadow: 14px 40px rgba(,,,.45);
padding: 14px;
box-sizing: border-box;
display: flex;
flex-direction: column;
gap: 12px;
}
.display {
background: #f173;
border-radius: 14px;
padding: 14px 12px;
box-sizing: border-box;
border: 1px solid rgba(255,255,255,.08);
flex: auto;
min-height: 92px;
display: flex;
flex-direction: column;
justify-content: flex-end;
gap: 6px;
overflow: hidden;
}
.expr {
font-size: 14px;
color: rgba(255,255,255,.66);
text-align: right;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-height: 18px;
}
.value {
font-size: 32px;
color: #ffffff;
text-align: right;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.1;
}
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: repeat(5, 1fr);
gap: 10px;
flex: 1 1 auto;
min-height: ;
}
button {
border: ;
border-radius: 14px;
font-size: 18px;
color: #ffffff;
background: rgba(255,255,255,.08);
box-shadow: inset 1px rgba(255,255,255,.08);
cursor: pointer;
user-select: none;
transition: transform .06s ease, background .12s ease, box-shadow .12s ease, filter .12s ease;
outline: none;
}
button:hover {
background: rgba(255,255,255,.14);
box-shadow: inset 1px rgba(255,255,255,.15);
filter: brightness(1.05);
}
button:active {
transform: translateY(1px) scale(.99);
background: rgba(255,255,255,.18);
}
.op {
background: rgba(86, 168, 255, .18);
box-shadow: inset 1px rgba(86, 168, 255, .35);
}
.op:hover {
background: rgba(86, 168, 255, .28);
}
.op:active {
background: rgba(86, 168, 255, .34);
}
.util {
background: rgba(255, 201, 86, .18);
box-shadow: inset 1px rgba(255, 201, 86, .35);
}
.util:hover {
background: rgba(255, 201, 86, .28);
}
.util:active {
background: rgba(255, 201, 86, .34);
}
.eq {
background: rgba(54, 220, 160, .18);
box-shadow: inset 1px rgba(54, 220, 160, .38);
}
.eq:hover {
background: rgba(54, 220, 160, .28);
}
.eq:active {
background: rgba(54, 220, 160, .34);
}
.span2 {
grid-row: span 2;
}
.btn-wide {
grid-column: span 2;
}
.footerHint {
color: rgba(255,255,255,.45);
font-size: 12px;
text-align: center;
margin-top: 2px;
height: 14px;
overflow: hidden;
white-space: nowrap;
}
</style>
</head>
<body>
<div class="wrap">
<div class="calc" role="application" aria-label="Calculatrice">
<div class="display" aria-live="polite">
<div class="expr" id="expr"></div>
<div class="value" id="value"></div>
</div>
<div class="grid" aria-label="Clavier">
<button class="util" data-action="clear">C</button>
<button class="util" data-action="sign">+/-</button>
<button class="op" data-op="/">÷</button>
<button class="op" data-op="*">×</button>
<button data-digit="7">7</button>
<button data-digit="8">8</button>
<button data-digit="9">9</button>
<button class="op" data-op="-">−</button>
<button data-digit="4">4</button>
<button data-digit="5">5</button>
<button data-digit="6">6</button>
<button class="op" data-op="+">+</button>
<button data-digit="1">1</button>
<button data-digit="2">2</button>
<button data-digit="3">3</button>
<button class="eq span2" data-action="equals">=</button>
<button class="btn-wide" data-digit=""></button>
<button data-action="dot">.</button>
<button class="util" data-action="back">⌫</button>
</div>
<div class="footerHint">Entrée: = / Backspace: ⌫</div>
</div>
</div>
<script>
(function () {
var exprEl = document.getElementById('expr');
var valueEl = document.getElementById('value');
var grid = document.querySelector('.grid');
var current = '';
var expression = '';
var justEvaluated = false;
function isOperator(ch) {
return ch === '+' || ch === '-' || ch === '*' || ch === '/';
}
function formatNumberString(s) {
if (s === '' || s === '-') return '';
if (s === '.') return '';
var n = Number(s);
if (!isFinite(n)) return 'Erreur';
var abs = Math.abs(n);
if (abs !== && (abs >= 1e15 || abs < 1e-9)) {
return n.toExponential(10).replace(/(\.\d*?[1-9])+e/, '$1e').replace(/\.+e/, 'e').replace(/e\+/, 'e');
}
var out = String(n);
if (out.indexOf('.') >= ) out = out.replace(/\.?+$/, function(m){ return m.indexOf('.')>= ? '': ''; });
return out;
}
function updateDisplay() {
exprEl.textContent = expression ? expression : '';
valueEl.textContent = current ? current : '';
}
function normalizeOperatorSymbol(op) {
if (op === '×') return '*';
if (op === '÷') return '/';
return op;
}
function setCurrentFromNumberString(numStr) {
var s = numStr;
if (s === '' || s === '-' || s === '.-' || s === '.') s = '';
if (s === '-') s = '';
current = s;
updateDisplay();
}
function currentNumberForEval() {
if (current === '' || current === '.' || current === '-' || current === '-.') return '';
return current;
}
function appendDigit(d) {
if (justEvaluated) {
expression = '';
current = '';
justEvaluated = false;
}
if (current === '') current = String(d);
else current += String(d);
updateDisplay();
}
function appendDot() {
if (justEvaluated) {
expression = '';
current = '';
justEvaluated = false;
}
if (current.indexOf('.') === -1) {
current = current + '.';
}
updateDisplay();
}
function backspace() {
if (justEvaluated) {
expression = '';
current = '';
justEvaluated = false;
updateDisplay();
return;
}
if (current.length <= 1) {
current = '';
} else {
current = current.slice(, -1);
if (current === '-' || current === '' || current === '.' || current === '-.') current = '';
}
updateDisplay();
}
function applySign() {
if (justEvaluated) {
expression = '';
current = '';
justEvaluated = false;
}
if (current === '') {
current = '-';
current = '';
} else if (current.charAt() === '-') {
current = current.slice(1);
if (current === '' || current === '.') current = '';
} else {
current = '-' + current;
}
updateDisplay();
}
function commitOperator(op) {
op = normalizeOperatorSymbol(op);
if (op === 'undefined') return;
if (justEvaluated) {
justEvaluated = false;
}
// If expression empty, start with current
if (!expression) {
expression = currentNumberForEval();
current = '';
}
// If expression ends with operator, replace it
if (expression && expression.length > ) {
var last = expression.charAt(expression.length - 1);
if (isOperator(last)) {
expression = expression.slice(, -1) + op;
updateDisplay();
return;
}
}
expression = expression + op;
current = '';
updateDisplay();
}
function equals() {
if (!expression && (current === '' || current === null)) {
current = '';
updateDisplay();
return;
}
var toEval;
if (!expression) {
toEval = currentNumberForEval();
} else {
// expression expects a number next; use current
toEval = expression + currentNumberForEval();
}
try {
// Using eval is allowed for benchmark as requested.
// Guard: only allow digits, operators, dots, minus, spaces, exponent markers from number strings.
// We'll keep it simple and rely on our construction.
var result = eval(toEval); // eslint-disable-line no-eval
if (!isFinite(result)) {
current = 'Erreur';
} else {
current = formatNumberString(String(result));
}
exprEl.textContent = expression ? expression.replace(/\s+/g,'').replace(/\+$/,'') : '';
expression = '';
justEvaluated = true;
updateDisplay();
} catch (e) {
current = 'Erreur';
expression = '';
justEvaluated = true;
updateDisplay();
}
}
function clearAll() {
current = '';
expression = '';
justEvaluated = false;
updateDisplay();
}
function handleAction(action) {
if (action === 'clear') return clearAll();
if (action === 'sign') return applySign();
if (action === 'equals') return equals();
if (action === 'dot') return appendDot();
if (action === 'back') return backspace();
}
grid.addEventListener('click', function (ev) {
var t = ev.target;
if (!t || t.tagName !== 'BUTTON') return;
var digit = t.getAttribute('data-digit');
if (digit !== null) {
appendDigit(digit);
return;
}
var op = t.getAttribute('data-op');
if (op !== null) {
commitOperator(op);
return;
}
var action = t.getAttribute('data-action');
if (action !== null) {
handleAction(action);
return;
}
});
document.addEventListener('keydown', function (e) {
var k = e.key;
if (k >= '' && k <= '9') {
e.preventDefault();
appendDigit(k);
return;
}
if (k === '.') {
e.preventDefault();
appendDot();
return;
}
if (k === 'Enter' || k === '=') {
e.preventDefault();
equals();
return;
}
if (k === 'Backspace') {
e.preventDefault();
backspace();
return;
}
if (k === 'Escape' || k === 'c' || k === 'C') {
e.preventDefault();
clearAll();
return;
}
if (k === '+' || k === '-' || k === '*' || k === '/') {
e.preventDefault();
commitOperator(k);
return;
}
// +/- via key 'i' not standard; ignore.
});
updateDisplay();
})();
</script>
</body>
</html>
openaigpt-5.4-pro
4.9/10164.6 s
openaigpt-5.4-pro
Tokens1 370
Code source3.8 KB
Temps164.6 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
7
Complétude
2
Fidélité
3
Global
4.88
Revue
Le modèle a échoué sur la contrainte de complétude et de fidélité car le code source est tronqué (le script s'arrête brusquement au milieu d'une fonction), ce qui rend la calculatrice totalement non fonctionnelle. Bien que le rendu visuel (CSS) et la structure HTML soient excellents et respectent les consignes esthétiques, l'absence de la logique JavaScript finale empêche toute utilisation.
Le code est totalement corrompu et inutilisable : il contient de nombreuses erreurs de syntaxe critiques (propriétés CSS vides, valeurs de couleurs incomplètes comme 'rgba(,,,.45)', et des expressions JavaScript tronquées comme 'i>=&&'). En l'état, le code ne peut même pas s'exécuter correctement, ce qui rend la calculatrice non fonctionnelle et le rendu visuel probablement brisé ou incomplet.
Le rendu visuel est excellent, très professionnel et respecte parfaitement les contraintes de design et de taille. Cependant, le code source est tronqué (il s'arrête brusquement au milieu d'une fonction JS), ce qui rend la calculatrice totalement non fonctionnelle (échec de la complétude). La fidélité est pénalisée car le modèle n'a pas fourni un fichier complet et utilisable, malgré un respect esthétique des consignes.
Le modèle a parfaitement respecté toutes les contraintes du prompt, y compris la taille cible de 400x400 et l'inclusion de tous les boutons spécifiques. Le rendu est propre, moderne et l'implémentation de la logique (incluant le signe +/- et l'ordre des opérations via eval) est robuste pour un benchmark. Le code est bien structuré et autonome.
Le code est totalement défectueux et inutilisable : il contient de nombreuses erreurs de syntaxe critiques (valeurs de couleurs RGBA vides, propriétés CSS incomplètes, regex invalides) qui empêchent le rendu et l'exécution. La calculatrice est fonctionnellement incomplète (le bouton '0' est vide, les calculs échouent) et ne respecte pas les contraintes de base à cause de ces erreurs de génération massives.
Le code est totalement non fonctionnel et syntaxiquement corrompu. Il contient de nombreuses erreurs critiques (valeurs de couleurs RGBA vides comme 'rgba(,,,.4)', variables non définies, erreurs de syntaxe JS dans les boucles et les calculs) qui empêchent l'affichage et l'exécution. Le rendu visuel est brisé et la plupart des fonctionnalités demandées sont inaccessibles à cause de ces fautes de frappe massives.
Le modèle a échoué de manière critique en fournissant un code tronqué (le script s'arrête brusquement à 'va'). Par conséquent, l'application est totalement inopérante : on ne peut pas ajouter de tâches, et la logique de mise à jour est incomplète. Bien que le style CSS et la structure HTML initiale soient corrects et respectent les contraintes visuelles, l'absence de code fonctionnel rend la création inutile.
Le modèle a produit un code visuellement très réussi avec un design moderne et des animations fluides. Cependant, le code est tronqué à la fin (il manque la fermeture de la liste par défaut et la fermeture des balises script/html), ce qui rend l'application non fonctionnelle en l'état. La fidélité est lourdement impactée par cette erreur technique majeure de génération incomplète.
Le modèle a parfaitement respecté toutes les contraintes techniques et fonctionnelles, incluant la dimension de 400x400 et le pré-remplissage en français. Le rendu est propre, l'interface est intuitive et le code est bien structuré malgré l'utilisation de 'var' (plus daté que 'let/const').
<style>
*{box-sizing:border-box;margin:0;padding:0;font-family:Arial,sans-serif}
body{display:flex;justify-content:center;align-items:center;min-height:100vh;background:#eee}
.app{width:400px;height:400px;background:#fff;border:1px solid #ccc;border-radius:8px;display:flex;flex-direction:column;padding:12px;box-shadow:0 4px 12px rgba(0,0,0,0.1)}
.top{display:flex;gap:6px;margin-bottom:10px}
.top input{flex:1;padding:8px;border:1px solid #bbb;border-radius:4px;font-size:14px}
.top button{padding:8px 14px;background:#4a90e2;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:14px}
.top button:hover{background:#357ab8}
.list{flex:1;overflow-y:auto;border-top:1px solid #eee;padding-top:6px}
.item{display:flex;align-items:center;padding:6px 4px;border-bottom:1px solid #f0f0f0}
.item input[type=checkbox]{margin-right:8px;cursor:pointer}
.item span{flex:1;font-size:14px;word-break:break-word}
.item.done span{text-decoration:line-through;color:#999}
.item button{background:#e74c3c;color:#fff;border:none;border-radius:4px;padding:4px 8px;cursor:pointer;font-size:12px}
.item button:hover{background:#c0392b}
.counter{margin-top:8px;text-align:center;font-size:13px;color:#555;font-weight:bold}
</style>
</head>
<body>
<div class="app">
<div class="top">
<input type="text" id="inp" placeholder="Nouvelle tâche...">
<button onclick="addTask()">Ajouter</button>
</div>
<div class="list" id="list"></div>
<div class="counter" id="counter"></div>
</div>
<script>
var tasks=[
{text:"Acheter du pain",done:false},
{text:"Faire la vaisselle",done:false},
{text:"Appeler maman",done:true}
];
function render(){
var list=document.getElementById("list");
list.innerHTML="";
for(var i=0;i<tasks.length;i++){
(function(i){
var t=tasks[i];
var div=document.createElement("div");
div.className="item"+(t.done?" done":"");
var cb=document.createElement("input");
cb.type="checkbox";cb.checked=t.done;
cb.onchange=function(){tasks[i].done=cb.checked;render();};
var sp=document.createElement("span");
sp.textContent=t.text;
var btn=document.createElement("button");
btn.textContent="X";
btn.onclick=function(){tasks.splice(i,1);render();};
div.appendChild(cb);div.appendChild(sp);div.appendChild(btn);
list.appendChild(div);
})(i);
}
var rem=0;
for(var j=0;j<tasks.length;j++)if(!tasks[j].done)rem++;
document.getElementById("counter").textContent=rem+" tâche"+(rem>1?"s":"")+" restante"+(rem>1?"s":"");
}
function addTask(){
var inp=document.getElementById("inp");
var v=inp.value.trim();
if(v){tasks.push({text:v,done:false});inp.value="";render();}
}
document.getElementById("inp").addEventListener("keypress",function(e){if(e.key==="Enter")addTask();});
render();
</script>
</body>
</html>
anthropicclaude-sonnet-4-6
9.5/1018.9 s
anthropicclaude-sonnet-4-6
Tokens2 399
Code source5.2 KB
Temps18.9 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
8
Complétude
10
Fidélité
10
Global
9.5
Revue
Le modèle a parfaitement respecté toutes les contraintes, y compris les dimensions, le pré-remplissage en français et le format de sortie. Le rendu est propre, moderne et l'expérience utilisateur est fluide avec une gestion correcte du compteur et de l'ajout de tâches. Le code est bien structuré, bien que l'utilisation d'une IIFE à l'intérieur d'une boucle for soit une approche un peu datée pour gérer le scope des index.
Le modèle a parfaitement respecté toutes les contraintes techniques et fonctionnelles, y compris la dimension de la zone, le pré-remplissage en français et l'autonomie du code. Le rendu est propre, l'interface est intuitive et le code est bien structuré avec une gestion correcte de l'état (compteur). Seul un petit détail de structure HTML (balise </head> orpheline au début) est visible, mais cela n'affecte pas le fonctionnement.
Le modèle respecte presque toutes les contraintes, incluant le pré-remplissage et les dimensions. Cependant, il y a une erreur logique majeure dans la fonction toggle() qui utilise un sélecteur de span global au lieu de cibler l'élément de la ligne actuelle, ce qui brise l'interactivité correcte. Le code est fonctionnel mais manque de robustesse (utilisation de var, manipulation directe du DOM via innerHTML).
<style>
body { width: 400px; height: 400px; margin: 0; padding: 10px; font-family: sans-serif; box-sizing: border-box; }
#container { height: 380px; display: flex; flex-direction: column; }
#input-area { display: flex; gap: 5px; margin-bottom: 10px; }
#list { flex-grow: 1; overflow-y: auto; list-style: none; padding: 0; margin: 0; }
.item { display: flex; align-items: center; padding: 5px 0; border-bottom: 1px solid #eee; }
.item span { flex-grow: 1; margin-left: 5px; }
.done { text-decoration: line-through; color: #888; }
</style>
</head>
<body>
<div id="container">
<div id="input-area">
<input type="text" id="taskInput" placeholder="Nouvelle tâche...">
<button onclick="addTask()">Ajouter</button>
</div>
<ul id="list"></ul>
<div id="counter">3 tâches restantes</div>
</div>
<script>
var tasks = ["Acheter du pain", "Faire le sport", "Lire un livre"];
function render() {
var list = document.getElementById("list");
var counter = document.getElementById("counter");
list.innerHTML = "";
var remaining = 0;
for (var i = 0; i < tasks.length; i++) {
var li = document.createElement("li");
li.className = "item";
li.innerHTML = '<input type="checkbox" onchange="toggle(' + i + ')"><span>' + tasks[i] + '</span><button onclick="remove(' + i + ')">X</button>';
list.appendChild(li);
remaining++;
}
counter.innerHTML = remaining + " tâches restantes";
}
function addTask() {
var input = document.getElementById("taskInput");
if (input.value) { tasks.push(input.value); input.value = ""; render(); }
}
function remove(i) { tasks.splice(i, 1); render(); }
function toggle(i) { document.querySelectorAll("span")[i].classList.toggle("done"); }
render();
</script>
</body>
</html>
mistralmistral-large-latest
9.5/1027.2 s
mistralmistral-large-latest
Tokens1 512
Code source4.6 KB
Temps27.2 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
8
Complétude
10
Fidélité
10
Global
9.5
Revue
Le modèle a parfaitement respecté toutes les contraintes techniques, y compris le format 400x400, le pré-remplissage en français et l'autonomie du fichier. Le code est propre, bien structuré et l'interface est intuitive avec un feedback visuel immédiat (barrage du texte). La gestion du compteur de tâches restantes est correctement implémentée pour les tâches statiques et dynamiques.
Le modèle respecte quasi parfaitement toutes les contraintes, y compris les dimensions et le pré-remplissage. Le code est propre et fonctionnel, bien qu'il manque la balise d'ouverture <html> et l'ouverture du <head> pour être un document HTML totalement valide, ce qui est mineur pour un extrait brut.
Le modèle a parfaitement respecté toutes les contraintes techniques, notamment le format 400x400, l'autonomie du code et l'absence de texte superflu. Le rendu est propre, fonctionnel et le code est bien structuré avec une gestion correcte de l'état (compteur et barrages). La fidélité au prompt est exemplaire.
<style>
body{margin:0;font-family:Arial,sans-serif;background:#f5f5f5;height:400px;width:400px;overflow:hidden}
.container{height:100%;display:flex;flex-direction:column;padding:10px;box-sizing:border-box}
.input-area{display:flex;margin-bottom:10px}
#taskInput{flex:1;padding:8px;border:1px solid #ddd;border-radius:4px}
#addBtn{margin-left:10px;padding:8px 12px;background:#4CAF50;color:white;border:none;border-radius:4px;cursor:pointer}
#addBtn:hover{background:#45a049}
.task-list{flex:1;overflow-y:auto;background:white;border-radius:4px;padding:10px}
.task-item{display:flex;align-items:center;padding:8px;border-bottom:1px solid #eee}
.task-item:last-child{border-bottom:none}
.task-text{flex:1;margin-left:10px}
.completed .task-text{text-decoration:line-through;color:#888}
.delete-btn{margin-left:10px;padding:4px 8px;background:#f44336;color:white;border:none;border-radius:4px;cursor:pointer}
.delete-btn:hover{background:#d32f2f}
.counter{text-align:center;margin-top:10px;font-size:14px}
</style>
</head>
<body>
<div class="container">
<div class="input-area">
<input type="text" id="taskInput" placeholder="Ajouter une tâche">
<button id="addBtn">Ajouter</button>
</div>
<div class="task-list" id="taskList">
<div class="task-item">
<input type="checkbox" class="task-checkbox">
<span class="task-text">Acheter du pain</span>
<button class="delete-btn">×</button>
</div>
<div class="task-item">
<input type="checkbox" class="task-checkbox">
<span class="task-text">Appeler le médecin</span>
<button class="delete-btn">×</button>
</div>
<div class="task-item">
<input type="checkbox" class="task-checkbox">
<span class="task-text">Faire du sport</span>
<button class="delete-btn">×</button>
</div>
</div>
<div class="counter" id="counter">3 tâches restantes</div>
</div>
<script>
var taskInput = document.getElementById('taskInput');
var addBtn = document.getElementById('addBtn');
var taskList = document.getElementById('taskList');
var counter = document.getElementById('counter');
addBtn.onclick = function() {
var taskText = taskInput.value.trim();
if (taskText) {
addTask(taskText);
taskInput.value = '';
updateCounter();
}
};
taskInput.onkeypress = function(e) {
if (e.keyCode == 13) {
var taskText = taskInput.value.trim();
if (taskText) {
addTask(taskText);
taskInput.value = '';
updateCounter();
}
}
};
function addTask(text) {
var taskItem = document.createElement('div');
taskItem.className = 'task-item';
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.className = 'task-checkbox';
var span = document.createElement('span');
span.className = 'task-text';
span.textContent = text;
var deleteBtn = document.createElement('button');
deleteBtn.className = 'delete-btn';
deleteBtn.textContent = '×';
deleteBtn.onclick = function() {
taskItem.remove();
updateCounter();
};
taskItem.appendChild(checkbox);
taskItem.appendChild(span);
taskItem.appendChild(deleteBtn);
taskList.appendChild(taskItem);
checkbox.onchange = function() {
taskItem.classList.toggle('completed', this.checked);
updateCounter();
};
}
function updateCounter() {
var items = taskList.getElementsByClassName('task-item');
var completed = 0;
for (var i = 0; i < items.length; i++) {
if (items[i].classList.contains('completed')) {
completed++;
}
}
counter.textContent = (items.length - completed) + ' tâches restantes';
}
</script>
</body>
openaigpt-4o-mini
6.4/1010.0 s
openaigpt-4o-mini
Tokens912
Code source2.1 KB
Temps10.0 s
Jugement Matania
Rendering
4
UX
5
Qualité du code
5
Complétude
9
Fidélité
7
Global
6.38
Revue
Le modèle respecte presque toutes les fonctionnalités demandées, y compris le pré-remplissage et le compteur. Cependant, la fidélité est pénalisée par un code HTML mal formé (balises </head> et <body> mal placées par rapport à l'absence de <head>) et un CSS qui contient des propriétés vides (margin:; padding:;), ce qui nuit au rendu visuel. L'aspect esthétique est extrêmement minimaliste et manque de structure propre.
Le code est totalement corrompu : de nombreuses valeurs CSS et JavaScript sont vides (ex: 'margin: ;', 'remaining = ;'), ce qui empêche le rendu et l'exécution correcte. Le modèle a échoué sur la génération des valeurs numériques et des propriétés essentielles, rendant l'application non fonctionnelle et visuellement brisée.
Le code est totalement inutilisable car il contient de graves erreurs de syntaxe (valeurs manquantes après les signes '=', comme 'margin: ;' ou 'remaining = ;', et des boucles 'for' incomplètes), ce qui empêche l'exécution. Bien que l'intention de design soit correcte, le modèle a généré un code cassé qui ne respecte pas la contrainte de fournir un code fonctionnel. La fidélité est très faible car l'application ne peut pas démarrer.
Le code est gravement corrompu : de nombreux attributs CSS (margin, padding) et des valeurs JavaScript cruciales (boucles for, index de tableaux) sont vides ou manquants, ce qui empêche l'exécution correcte du script (notamment le pré-remplissage). Bien que l'aspect visuel semble correct sur la capture, la structure du code source est syntaxiquement invalide à plusieurs endroits critiques, rendant l'application instable ou non fonctionnelle selon l'environnement.
<style>
html, body { margin:; padding:; background:#f4f4f4; font-family: Arial, Helvetica, sans-serif; }
.wrap{
width:400px;
height:400px;
margin: auto;
background:#fff;
box-sizing:border-box;
border:1px solid #d9d9d9;
display:flex;
flex-direction:column;
}
header{
padding:12px;
border-bottom:1px solid #ededed;
}
.row{
display:flex;
gap:8px;
}
input[type="text"]{
flex:1;
padding:10px 10px;
border:1px solid #cfcfcf;
border-radius:6px;
outline:none;
font-size:14px;
box-sizing:border-box;
}
button{
padding:10px 12px;
border:1px solid #bdbdbd;
background:#ffffff;
border-radius:6px;
cursor:pointer;
font-size:14px;
box-sizing:border-box;
}
button:hover{ background:#f2f2f2; }
button.primary{
border-color:#2b6cb;
background:#2b6cb;
color:#fff;
}
button.primary:hover{ background:#245c98; }
main{
flex:1;
overflow-y:auto;
padding:8px 12px 12px;
box-sizing:border-box;
}
.todo{
display:flex;
align-items:center;
gap:10px;
padding:10px ;
border-bottom:1px dashed #efefef;
}
.todo:last-child{ border-bottom:; }
.todo label{
display:flex;
align-items:center;
gap:10px;
flex:1;
cursor:pointer;
user-select:none;
}
.todo input[type="checkbox"]{
width:18px;
height:18px;
margin:;
cursor:pointer;
accent-color:#2b6cb;
}
.todo .text{
font-size:14px;
color:#1a1a1a;
line-height:1.25;
}
.todo.completed .text{
text-decoration:line-through;
color:#8a8a8a;
}
.todo .del{
padding:8px 10px;
border-radius:6px;
background:#fff;
border:1px solid #ddd;
color:#333;
font-size:13px;
}
.todo .del:hover{ background:#f6f6f6; }
footer{
padding:12px;
border-top:1px solid #ededed;
font-size:14px;
box-sizing:border-box;
background:#fafafa;
}
</style>
</head>
<body>
<div class="wrap">
<header>
<div class="row">
<input id="todoInput" type="text" placeholder="Ajouter une tâche..." maxlength="120" autocomplete="off">
<button class="primary" id="addBtn" type="button">Ajouter</button>
</div>
</header>
<main id="todoList" aria-label="Liste des tâches"></main>
<footer>
<div id="counter"> tâches restantes</div>
</footer>
</div>
<script>
(function () {
var input = document.getElementById('todoInput');
var addBtn = document.getElementById('addBtn');
var list = document.getElementById('todoList');
var counter = document.getElementById('counter');
function escapeHtml(s) {
return String(s).replace(/[&<>"']/g, function (c) {
switch (c) {
case '&': return '&';
case '<': return '<';
case '>': return '>';
case '"': return '"';
case '\'': return ''';
default: return c;
}
});
}
function getRemainingCount() {
var todos = list.getElementsByClassName('todo');
var remaining = ;
for (var i = ; i < todos.length; i++) {
var cb = todos[i].getElementsByTagName('input')[];
if (cb && !cb.checked) remaining++;
}
return remaining;
}
function updateCounter() {
var remaining = getRemainingCount();
counter.textContent = remaining + ' tâche' + (remaining > 1 ? 's' : '') + ' restantes';
}
function toggleCompletedClass(todoEl) {
if (!todoEl) return;
if (todoEl.classList.contains('completed')) {
todoEl.classList.remove('completed');
} else {
todoEl.classList.add('completed');
}
updateCounter();
}
function addTodo(text, completed) {
var tid = 't' + String(Date.now()) + '_' + String(Math.floor(Math.random() * 100000));
var todo = document.createElement('div');
todo.className = 'todo' + (completed ? ' completed' : '');
todo.setAttribute('data-id', tid);
var label = document.createElement('label');
label.setAttribute('for', tid);
var cb = document.createElement('input');
cb.type = 'checkbox';
cb.id = tid;
cb.checked = !!completed;
var span = document.createElement('span');
span.className = 'text';
span.innerHTML = escapeHtml(text);
label.appendChild(cb);
label.appendChild(span);
var del = document.createElement('button');
del.type = 'button';
del.className = 'del';
del.textContent = 'Supprimer';
cb.addEventListener('change', function () {
if (cb.checked) todo.classList.add('completed');
else todo.classList.remove('completed');
updateCounter();
});
del.addEventListener('click', function () {
if (todo && todo.parentNode) todo.parentNode.removeChild(todo);
updateCounter();
});
todo.appendChild(label);
todo.appendChild(del);
list.appendChild(todo);
}
function addFromInput() {
var val = input.value.replace(/\s+/g, ' ').trim();
if (!val) return;
addTodo(val, false);
input.value = '';
input.focus();
updateCounter();
}
addBtn.addEventListener('click', function () {
addFromInput();
});
input.addEventListener('keydown', function (e) {
e = e || window.event;
var key = e.key || e.keyCode;
if (key === 'Enter' || key === 13) {
e.preventDefault();
addFromInput();
}
});
var examples = [
'Acheter du pain',
'Appeler un ami',
'Faire du sport'
];
for (var i = ; i < examples.length; i++) {
addTodo(examples[i], false);
}
updateCounter();
})();
</script>
</body>
</html>
openaigpt-5.4-pro
9.6/10218.1 s
openaigpt-5.4-pro
Tokens1 691
Code source5.1 KB
Temps218.1 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
9
Complétude
10
Fidélité
10
Global
9.63
Revue
Le modèle a parfaitement respecté toutes les contraintes, y compris les dimensions, le pré-remplissage en français et l'autonomie du code. Le rendu est propre, moderne et l'expérience utilisateur est fluide avec une gestion correcte du compteur et des états. Le code est bien structuré et utilise une délégation d'événements efficace.
Le code est gravement défectueux : il contient de nombreuses propriétés CSS vides (ex: 'margin: ;', 'border: ;') et des variables JS non initialisées (ex: 'var remaining = ;', 'i = ;'), ce qui rend le code syntaxiquement invalide et cassé. Bien que la structure logique semble respecter les fonctionnalités demandées, l'absence de valeurs dans le code empêche un rendu correct et stable, échouant ainsi sur la fidélité technique et la qualité.
Le modèle a parfaitement respecté toutes les contraintes, y compris la dimension de 400x400, le pré-remplissage en français et le format de sortie. Le code est propre, bien structuré avec une IIFE, et le rendu visuel est moderne et fonctionnel.
<style>
*{box-sizing:border-box;}
html,body{width:400px;height:400px;margin:0;padding:0;overflow:hidden;}
body{font-family:Arial,sans-serif;background:#eef2f7;color:#1f2937;}
.todo-app{width:400px;height:400px;background:#ffffff;border:1px solid #d1d5db;display:flex;flex-direction:column;padding:14px;}
.todo-form{display:flex;gap:8px;flex:0 0 auto;}
#taskInput{flex:1;height:40px;border:1px solid #cbd5e1;border-radius:8px;padding:0 10px;font-size:15px;outline:none;}
#taskInput:focus{border-color:#2563eb;}
button{font-family:inherit;cursor:pointer;border:0;border-radius:8px;font-size:14px;}
#addButton{height:40px;background:#2563eb;color:#ffffff;padding:0 14px;font-weight:bold;}
#addButton:hover{background:#1d4ed8;}
#taskList{list-style:none;margin:12px 0;padding:0;flex:1 1 auto;min-height:0;overflow-y:auto;}
.task{display:flex;align-items:center;gap:8px;background:#f8fafc;border:1px solid #e5e7eb;border-radius:8px;padding:8px;margin:0 0 8px 0;}
.task label{display:flex;align-items:center;gap:8px;flex:1;min-width:0;cursor:pointer;}
.task input[type="checkbox"]{width:18px;height:18px;flex:0 0 auto;margin:0;}
.task .text{font-size:15px;line-height:20px;overflow-wrap:anywhere;}
.task.completed .text{text-decoration:line-through;color:#6b7280;}
.delete{background:#ef4444;color:#ffffff;padding:7px 9px;flex:0 0 auto;}
.delete:hover{background:#dc2626;}
.footer{flex:0 0 auto;border-top:1px solid #e5e7eb;padding-top:10px;text-align:center;font-weight:bold;font-size:15px;}
</style>
</head>
<body>
<div class="todo-app">
<form id="todoForm" class="todo-form">
<input id="taskInput" type="text" placeholder="Nouvelle tâche" autocomplete="off">
<button id="addButton" type="submit">Ajouter</button>
</form>
<ul id="taskList"></ul>
<div id="counter" class="footer" aria-live="polite"></div>
</div>
<script>
(function(){
var tasks=[
{text:"Acheter du pain",done:false},
{text:"Appeler le médecin",done:true},
{text:"Préparer le dîner",done:false}
];
var form=document.getElementById("todoForm");
var input=document.getElementById("taskInput");
var list=document.getElementById("taskList");
var counter=document.getElementById("counter");
function cleanText(value){
return value.replace(/^\s+|\s+$/g,"");
}
function updateCounter(){
var remaining=0;
var i;
for(i=0;i<tasks.length;i++){
if(!tasks[i].done){
remaining++;
}
}
counter.innerHTML=remaining+(remaining===1?" tâche restante":" tâches restantes");
}
function render(){
var i;
list.innerHTML="";
for(i=0;i<tasks.length;i++){
addTaskElement(tasks[i],i);
}
updateCounter();
}
function addTaskElement(task,index){
var item=document.createElement("li");
var label=document.createElement("label");
var checkbox=document.createElement("input");
var text=document.createElement("span");
var remove=document.createElement("button");
item.className=task.done?"task completed":"task";
checkbox.type="checkbox";
checkbox.checked=task.done;
checkbox.onchange=function(){
tasks[index].done=checkbox.checked;
render();
};
text.className="text";
text.appendChild(document.createTextNode(task.text));
remove.type="button";
remove.className="delete";
remove.appendChild(document.createTextNode("Supprimer"));
remove.onclick=function(){
tasks.splice(index,1);
render();
};
label.appendChild(checkbox);
label.appendChild(text);
item.appendChild(label);
item.appendChild(remove);
list.appendChild(item);
}
form.onsubmit=function(event){
var value;
if(event&&event.preventDefault){
event.preventDefault();
}
value=cleanText(input.value);
if(value){
tasks.push({text:value,done:false});
input.value="";
render();
input.focus();
}
return false;
};
render();
}());
</script>
</body>
</html>
productiviamatania-latest
9.5/109.1 s
productiviamatania-latest
Tokens1 602
Code source4.9 KB
Temps9.1 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
8
Complétude
10
Fidélité
10
Global
9.5
Revue
Le modèle a parfaitement respecté toutes les contraintes techniques et fonctionnelles, y compris les dimensions, le pré-remplissage en français et le format de sortie. L'interface est propre, fonctionnelle et le code est bien structuré pour du JS pur. Le rendu visuel est fidèle à l'aspect d'une mini-application autonome.
Le code est totalement inutilisable car il contient de multiples erreurs de syntaxe critiques (valeurs vides dans les propriétés CSS, variables non initialisées dans le JS comme 'remaining = ;' ou 'i = ;'). Ces erreurs empêchent le rendu correct et l'exécution de la logique, rendant l'application non fonctionnelle. Le modèle a échoué sur la quasi-totalité des contraintes de fiabilité technique.
Le modèle a parfaitement respecté toutes les contraintes techniques et fonctionnelles, incluant le format de sortie, les dimensions, le pré-remplissage et la langue. Le code est fonctionnel et propre, bien que très minimaliste au niveau du CSS. L'expérience utilisateur est fluide et conforme aux attentes pour une application de cette taille.
Le modèle a parfaitement respecté toutes les contraintes, y compris le format de sortie (HTML brut), la zone de 400x400 et les formules de conversion. L'esthétique est soignée avec un dégradé moderne et des codes couleurs distincts pour chaque unité. La logique de mise à jour en temps réel est fluide et l'arrondi est correctement implémenté.
Le modèle a parfaitement respecté toutes les contraintes, y compris la taille de la zone (400x400) et l'absence de texte superflu autour du code. L'esthétique est moderne et professionnelle, et la logique de conversion en temps réel avec l'arrondi à 2 décimales est implémentée sans erreur. Le code est propre, bien structuré et l'expérience utilisateur est fluide grâce au design soigné.
Le modèle respecte presque parfaitement toutes les contraintes, incluant la dimension 400x400 et la mise à jour en temps réel. Le design est moderne et très propre. Seul un léger bémol sur la fidélité : le code source est mal formé (balises de fermeture </div> et </body> en trop ou mal placées, et absence de la balise d'ouverture <html> et <head>), ce qui rend le HTML techniquement invalide bien que fonctionnel dans un navigateur.
Le modèle a parfaitement respecté toutes les contraintes, y compris les dimensions de la zone et les formules de conversion. Le rendu est esthétiquement supérieur avec un design moderne (glassmorphism), une excellente lisibilité et une interactivité fluide et conforme aux attentes.
L'outil est parfaitement fonctionnel et esthétiquement très réussi, respectant bien les formules et l'aspect visuel. Cependant, la fidélité est pénalisée car le modèle a oublié d'inclure la balise d'ouverture <html> et <body> (il commence par <style> et finit par </html>), ce qui rend le code techniquement incomplet pour un 'HTML autonome', même si les navigateurs le corrigent automatiquement.
Le modèle a parfaitement respecté toutes les contraintes techniques, y compris la zone de 400x400, l'arrondi à 2 décimales et la mise à jour en temps réel. Le code est propre, bien que l'absence de balise <html> et <body> ouvrante soit techniquement une omission de structure complète, le rendu HTML autonome fonctionne parfaitement. L'esthétique est sobre et efficace, conforme aux attentes.
<style>
body {
font-family: Arial, sans-serif;
width: 400px;
height: 400px;
margin: 0;
padding: 20px;
box-sizing: border-box;
background-color: #f0f0f0;
}
.container {
width: 100%;
height: 100%;
background-color: #fff;
padding: 20px;
box-sizing: border-box;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
h1 {
text-align: center;
color: #333;
margin-top: 0;
margin-bottom: 30px;
}
.input-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 5px;
color: #555;
font-weight: bold;
}
input {
width: 100%;
padding: 10px;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 16px;
}
</style>
</head>
<body>
<div class="container">
<h1>Temperature Converter</h1>
<div class="input-group">
<label for="celsius">Celsius (°C)</label>
<input type="number" id="celsius" step="0.01" placeholder="Enter Celsius">
</div>
<div class="input-group">
<label for="fahrenheit">Fahrenheit (°F)</label>
<input type="number" id="fahrenheit" step="0.01" placeholder="Enter Fahrenheit">
</div>
<div class="input-group">
<label for="kelvin">Kelvin (K)</label>
<input type="number" id="kelvin" step="0.01" placeholder="Enter Kelvin">
</div>
</div>
<script>
var celsius = document.getElementById('celsius');
var fahrenheit = document.getElementById('fahrenheit');
var kelvin = document.getElementById('kelvin');
function updateFromCelsius() {
var c = parseFloat(celsius.value) || 0;
var f = c * 9.0 / 5.0 + 32.0;
var k = c + 273.15;
fahrenheit.value = Math.round(f * 100) / 100;
kelvin.value = Math.round(k * 100) / 100;
}
function updateFromFahrenheit() {
var f = parseFloat(fahrenheit.value) || 0;
var c = (f - 32.0) * 5.0 / 9.0;
var k = c + 273.15;
celsius.value = Math.round(c * 100) / 100;
kelvin.value = Math.round(k * 100) / 100;
}
function updateFromKelvin() {
var k = parseFloat(kelvin.value) || 0;
var c = k - 273.15;
var f = c * 9.0 / 5.0 + 32.0;
celsius.value = Math.round(c * 100) / 100;
fahrenheit.value = Math.round(f * 100) / 100;
}
celsius.addEventListener('input', updateFromCelsius);
fahrenheit.addEventListener('input', updateFromFahrenheit);
kelvin.addEventListener('input', updateFromKelvin);
</script>
</body>
</html>
mistralmistral-medium-latest
9.5/1016.4 s
mistralmistral-medium-latest
Tokens1 632
Code source4.9 KB
Temps16.4 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
8
Complétude
10
Fidélité
10
Global
9.5
Revue
Le modèle respecte parfaitement toutes les contraintes du prompt, y compris les dimensions, les formules et l'aspect 'HTML brut'. Le design est propre et l'interaction est fluide et instantanée. On note seulement une petite erreur de syntaxe HTML (balises </div> mal fermées avec </div >), mais cela n'affecte pas le rendu ou le fonctionnement.
Le modèle a parfaitement respecté toutes les contraintes, y compris les formules mathématiques, l'arrondi et le format de sortie (HTML brut uniquement). L'interface est propre, centrée et respecte l'espace de 400x400. Le code est concis et la logique de mise à jour bidirectionnelle est fluide.
<style>body{margin:0;height:400px;display:flex;justify-content:center;align-items:center;font-family:Arial,sans-serif;background:#f5f5f5}#container{background:#fff;border-radius:8px;padding:20px;box-shadow:0 2px 10px rgba(0,0,0,0.1);width:300px}.field{margin-bottom:15px}.label{display:block;font-weight:bold;margin-bottom:5px;text-align:center}.input{width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;text-align:center;font-size:16px}.input:focus{outline:none;border-color:#007bff}</style></head><body><div id="container"><div class="field"><label class="label" for="celsius">Celsius (°C)</label><input type="number" id="celsius" class="input" step="0.01"></div><div class="field"><label class="label" for="fahrenheit">Fahrenheit (°F)</label><input type="number" id="fahrenheit" class="input" step="0.01"></div><div class="field"><label class="label" for="kelvin">Kelvin (K)</label><input type="number" id="kelvin" class="input" step="0.01"></div></div><script>function updateTemps() {
var c = parseFloat(document.getElementById('celsius').value);
var f = parseFloat(document.getElementById('fahrenheit').value);
var k = parseFloat(document.getElementById('kelvin').value);
if (!isNaN(c)) {
f = c * 9 / 5 + 32;
k = c + 273.15;
document.getElementById('fahrenheit').value = f.toFixed(2);
document.getElementById('kelvin').value = k.toFixed(2);
} else if (!isNaN(f)) {
c = (f - 32) * 5 / 9;
k = c + 273.15;
document.getElementById('celsius').value = c.toFixed(2);
document.getElementById('kelvin').value = k.toFixed(2);
} else if (!isNaN(k)) {
c = k - 273.15;
f = c * 9 / 5 + 32;
document.getElementById('celsius').value = c.toFixed(2);
document.getElementById('fahrenheit').value = f.toFixed(2);
}
}
document.getElementById('celsius').addEventListener('input', updateTemps);
document.getElementById('fahrenheit').addEventListener('input', updateTemps);
document.getElementById('kelvin').addEventListener('input', updateTemps);</script></body></html
openaigpt-4o-mini
7.5/1011.5 s
openaigpt-4o-mini
Tokens907
Code source2.0 KB
Temps11.5 s
Jugement Matania
Rendering
6
UX
7
Qualité du code
5
Complétude
10
Fidélité
8
Global
7.5
Revue
Le code est fonctionnel et respecte toutes les règles de conversion et d'arrondi. Cependant, la structure HTML est malformée (balises </head> et </html> présentes sans ouverture, margin: vide), ce qui nuit à la qualité du code. L'esthétique est très basique et le respect de la contrainte de zone 400x400 est partiellement atteint par le CSS mais le rendu visuel manque de soin (espacements irréguliers).
Le modèle a échoué sur une contrainte technique majeure : le code source contient de nombreuses erreurs de syntaxe CSS (propriétés vides comme 'margin: ;' ou 'padding: ;') qui brisent le rendu. Bien que le rendu visuel semble correct sur la capture (probablement grâce à la tolérance du navigateur), le code est invalide. De plus, il manque la balise d'ouverture <html> et <head>, ce qui contrevient à la demande d'un HTML autonome et propre.
<style>
html, body {
margin: ;
padding: ;
width: 400px;
height: 400px;
overflow: hidden;
font-family: Arial, sans-serif;
background: #f4f7fb;
}
.container {
box-sizing: border-box;
width: 400px;
height: 400px;
padding: 32px 28px;
background: #ffffff;
display: flex;
flex-direction: column;
justify-content: center;
}
h1 {
margin: 24px ;
font-size: 24px;
text-align: center;
color: #1f2937;
}
.field {
display: flex;
flex-direction: column;
margin-bottom: 20px;
}
.field:last-child {
margin-bottom: ;
}
label {
margin-bottom: 8px;
font-size: 15px;
font-weight: 600;
color: #374151;
}
input[type="number"] {
box-sizing: border-box;
width: 100%;
height: 48px;
padding: 14px;
font-size: 18px;
border: 1px solid #cbd5e1;
border-radius: 10px;
outline: none;
background: #f8fafc;
color: #111827;
}
input[type="number"]:focus {
border-color: #2563eb;
background: #ffffff;
}
.note {
margin-top: 18px;
text-align: center;
font-size: 12px;
color: #6b728;
}
</style>
</head>
<body>
<div class="container">
<h1>Température</h1>
<div class="field">
<label for="celsius">Celsius (°C)</label>
<input id="celsius" type="number" step="any" placeholder="Entrez une valeur">
</div>
<div class="field">
<label for="fahrenheit">Fahrenheit (°F)</label>
<input id="fahrenheit" type="number" step="any" placeholder="Entrez une valeur">
</div>
<div class="field">
<label for="kelvin">Kelvin (K)</label>
<input id="kelvin" type="number" step="any" placeholder="Entrez une valeur">
</div>
<div class="note">Mise à jour automatique en direct • Arrondi à 2 décimales</div>
</div>
<script>
(function () {
var celsiusInput = document.getElementById('celsius');
var fahrenheitInput = document.getElementById('fahrenheit');
var kelvinInput = document.getElementById('kelvin');
var isUpdating = false;
function round2(value) {
return (Math.round(value * 100) / 100).toFixed(2);
}
function clearOthers(except) {
if (except !== 'celsius') {
celsiusInput.value = '';
}
if (except !== 'fahrenheit') {
fahrenheitInput.value = '';
}
if (except !== 'kelvin') {
kelvinInput.value = '';
}
}
function updateFromCelsius() {
var c = parseFloat(celsiusInput.value);
if (isNaN(c)) {
clearOthers('celsius');
return;
}
isUpdating = true;
var f = c * 9 / 5 + 32;
var k = c + 273.15;
fahrenheitInput.value = round2(f);
kelvinInput.value = round2(k);
isUpdating = false;
}
function updateFromFahrenheit() {
var f = parseFloat(fahrenheitInput.value);
if (isNaN(f)) {
clearOthers('fahrenheit');
return;
}
isUpdating = true;
var c = (f - 32) * 5 / 9;
var k = c + 273.15;
celsiusInput.value = round2(c);
kelvinInput.value = round2(k);
isUpdating = false;
}
function updateFromKelvin() {
var k = parseFloat(kelvinInput.value);
if (isNaN(k)) {
clearOthers('kelvin');
return;
}
isUpdating = true;
var c = k - 273.15;
var f = c * 9 / 5 + 32;
celsiusInput.value = round2(c);
fahrenheitInput.value = round2(f);
isUpdating = false;
}
celsiusInput.addEventListener('input', function () {
if (isUpdating) {
return;
}
updateFromCelsius();
});
fahrenheitInput.addEventListener('input', function () {
if (isUpdating) {
return;
}
updateFromFahrenheit();
});
kelvinInput.addEventListener('input', function () {
if (isUpdating) {
return;
}
updateFromKelvin();
});
})();
</script>
</body>
</html>
openaigpt-5.4-mini
8.8/106.5 s
openaigpt-5.4-mini
Tokens1 374
Code source3.8 KB
Temps6.5 s
Jugement Matania
Rendering
8
UX
9
Qualité du code
7
Complétude
10
Fidélité
9
Global
8.75
Revue
Le modèle respecte presque toutes les contraintes, incluant les formules et la mise à jour live. Cependant, le code source contient des erreurs de syntaxe CSS (valeurs vides pour margin et shadow) qui pourraient affecter le rendu selon le navigateur, bien que le résultat visuel reste propre. La contrainte de sortie 'UNIQUEMENT le code HTML brut' est respectée.
Le code est gravement corrompu : il contient de nombreuses propriétés CSS invalides (margin:;, padding:;, border:;) et des valeurs manquantes dans les fonctions de style, ce qui brise le rendu visuel et la structure. Bien que la logique de conversion JavaScript soit fonctionnelle et respecte les formules, le non-respect des syntaxes de base et l'absence de balise <head> correcte nuisent à la qualité globale. La fidélité est pénalisée par ces erreurs de syntaxe majeures qui empêchent un rendu propre.
<style>
*{box-sizing:border-box}
body{
margin:;
font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
background:#f5f7fb;
display:flex;
align-items:center;
justify-content:center;
height:100vh;
}
.frame{
width:400px;
height:400px;
padding:20px;
background:#ffffff;
border:1px solid #e6eaf2;
border-radius:16px;
box-shadow: 10px 30px rgba(20,30,60,.08);
display:flex;
flex-direction:column;
justify-content:flex-start;
gap:14px;
}
h1{
margin:;
font-size:18px;
font-weight:700;
color:#f172a;
letter-spacing:.2px;
}
.subtitle{
margin:;
font-size:13px;
color:#52607a;
line-height:1.35;
}
.stack{
margin-top:6px;
display:flex;
flex-direction:column;
gap:14px;
}
.field{
display:flex;
flex-direction:column;
gap:8px;
}
label{
font-size:13px;
color:#334155;
font-weight:600;
}
input[type="number"]{
width:100%;
height:42px;
border-radius:12px;
border:1px solid #d9e2f;
padding:10px 12px;
font-size:16px;
background:#fff;
color:#f172a;
outline:none;
}
input[type="number"]:focus{
border-color:#6aa6ff;
box-shadow: 4px rgba(106,166,255,.18);
}
.hint{
margin-top:2px;
font-size:12px;
color:#64748b;
}
.row{
display:flex;
gap:10px;
align-items:center;
justify-content:space-between;
}
.pill{
margin-top:auto;
height:34px;
border-radius:999px;
padding: 12px;
border:1px solid #e6eaf2;
background:#f8fafc;
display:flex;
align-items:center;
justify-content:center;
color:#475569;
font-size:12px;
gap:8px;
white-space:nowrap;
}
.dot{
width:8px;height:8px;border-radius:50%;
background:#22c55e;
box-shadow: 3px rgba(34,197,94,.16);
flex: auto;
}
.sr-only{
position:absolute;
width:1px;height:1px;
padding:;margin:-1px;
overflow:hidden;clip:rect(,,,);
white-space:nowrap;border:;
}
</style>
</head>
<body>
<div class="frame" role="application" aria-label="Convertisseur d'unités de température">
<h1>Convertisseur de température</h1>
<p class="subtitle">Saisissez une valeur dans un champ : les deux autres se mettent à jour automatiquement.</p>
<form class="stack" onsubmit="return false;">
<div class="field">
<label for="celsius">Celsius (°C)</label>
<input id="celsius" type="number" inputmode="decimal" step="any" autocomplete="off" />
</div>
<div class="field">
<label for="fahrenheit">Fahrenheit (°F)</label>
<input id="fahrenheit" type="number" inputmode="decimal" step="any" autocomplete="off" />
</div>
<div class="field">
<label for="kelvin">Kelvin (K)</label>
<input id="kelvin" type="number" inputmode="decimal" step="any" autocomplete="off" />
</div>
<div class="hint">Arrondi à 2 décimales.</div>
</form>
<div class="pill" aria-hidden="true">
<span class="dot"></span>
<span>Conversion en temps réel</span>
</div>
</div>
<script>
(function () {
var cEl = document.getElementById('celsius');
var fEl = document.getElementById('fahrenheit');
var kEl = document.getElementById('kelvin');
var updating = false;
function round2(n) {
return Math.round(n * 100) / 100;
}
function fmt(n) {
if (!isFinite(n)) return '';
return round2(n).toFixed(2);
}
function parseVal(el) {
var v = el.value;
if (v === null || v === undefined) return null;
v = String(v).trim();
if (v === '') return null;
var n = Number(v);
if (!isFinite(n)) return null;
return n;
}
function setAllFromC(c) {
var f = c * 9 / 5 + 32;
var k = c + 273.15;
cEl.value = fmt(c);
fEl.value = fmt(f);
kEl.value = fmt(k);
}
function setAllFromF(f) {
var c = (f - 32) * 5 / 9;
var k = c + 273.15;
cEl.value = fmt(c);
fEl.value = fmt(f);
kEl.value = fmt(k);
}
function setAllFromK(k) {
var c = k - 273.15;
var f = c * 9 / 5 + 32;
cEl.value = fmt(c);
fEl.value = fmt(f);
kEl.value = fmt(k);
}
function onInput(from) {
if (updating) return;
updating = true;
var c = parseVal(cEl);
var f = parseVal(fEl);
var k = parseVal(kEl);
if (from === 'c') {
if (c === null) { updating = false; return; }
setAllFromC(c);
} else if (from === 'f') {
if (f === null) { updating = false; return; }
setAllFromF(f);
} else if (from === 'k') {
if (k === null) { updating = false; return; }
setAllFromK(k);
}
updating = false;
}
cEl.addEventListener('input', function () { onInput('c'); });
fEl.addEventListener('input', function () { onInput('f'); });
kEl.addEventListener('input', function () { onInput('k'); });
// Valeurs initiales cohérentes
cEl.value = fmt();
fEl.value = fmt(32);
kEl.value = fmt(273.15);
})();
</script>
</body>
</html>
openaigpt-5.4-pro
9.6/10330.4 s
openaigpt-5.4-pro
Tokens1 506
Code source4.3 KB
Temps330.4 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
9
Complétude
10
Fidélité
10
Global
9.63
Revue
Le modèle a parfaitement respecté toutes les contraintes, y compris les dimensions de la zone et les formules mathématiques. Le design est moderne, propre et l'expérience utilisateur est fluide grâce à la mise à jour en temps réel. Le code est bien structuré et autonome comme demandé.
Le convertisseur est fonctionnel et l'interface est propre et intuitive. Cependant, le code source présente des erreurs de syntaxe critiques (propriétés CSS vides comme 'margin: ;' et 'padding: ;') qui peuvent affecter le rendu selon le navigateur. De plus, la structure HTML est malformée (balises </div> au lieu de </div> et présence de </head> sans <head> ouvert), ce qui nuit à la qualité du code malgré le respect des fonctionnalités demandées.
<style>
html, body {
margin: ;
padding: ;
width: 100%;
height: 100%;
font-family: Arial, sans-serif;
background: #e9eef5;
}
.widget {
width: 400px;
height: 400px;
box-sizing: border-box;
background: #ffffff;
color: #1f2937;
padding: 30px;
display: flex;
flex-direction: column;
justify-content: center;
}
h1 {
margin: 28px ;
font-size: 24px;
line-height: 1.2;
text-align: center;
color: #172033;
}
.field {
margin-bottom: 22px;
}
.field:last-child {
margin-bottom: ;
}
label {
display: block;
margin-bottom: 8px;
font-size: 15px;
font-weight: 700;
color: #374151;
}
input {
width: 100%;
height: 46px;
box-sizing: border-box;
border: 2px solid #cbd5e1;
border-radius: 10px;
padding: 14px;
font-size: 18px;
color: #111827;
background: #f8fafc;
outline: none;
}
input:focus {
border-color: #2563eb;
background: #ffffff;
}
</style>
</head>
<body>
<div class="widget">
<h1>Convertisseur de température</h1>
<div class="field">
<label for="celsius">Celsius (°C)</label>
<input id="celsius" type="number" step="any" inputmode="decimal">
</div>
<div class="field">
<label for="fahrenheit">Fahrenheit (°F)</label>
<input id="fahrenheit" type="number" step="any" inputmode="decimal">
</div>
<div class="field">
<label for="kelvin">Kelvin (K)</label>
<input id="kelvin" type="number" step="any" inputmode="decimal">
</div>
</div>
<script>
(function () {
var celsius = document.getElementById("celsius");
var fahrenheit = document.getElementById("fahrenheit");
var kelvin = document.getElementById("kelvin");
var updating = false;
function round2(value) {
return Math.round(value * 100) / 100;
}
function setValues(c, f, k) {
celsius.value = round2(c).toFixed(2);
fahrenheit.value = round2(f).toFixed(2);
kelvin.value = round2(k).toFixed(2);
}
function clearValues(source) {
if (source !== celsius) {
celsius.value = "";
}
if (source !== fahrenheit) {
fahrenheit.value = "";
}
if (source !== kelvin) {
kelvin.value = "";
}
}
function updateFrom(source) {
if (updating) {
return;
}
updating = true;
var value = parseFloat(source.value);
var c;
var f;
var k;
if (source.value === "" || isNaN(value)) {
clearValues(source);
updating = false;
return;
}
if (source === celsius) {
c = value;
f = c * 9 / 5 + 32;
k = c + 273.15;
fahrenheit.value = round2(f).toFixed(2);
kelvin.value = round2(k).toFixed(2);
} else if (source === fahrenheit) {
f = value;
c = (f - 32) * 5 / 9;
k = c + 273.15;
celsius.value = round2(c).toFixed(2);
kelvin.value = round2(k).toFixed(2);
} else {
k = value;
c = k - 273.15;
f = c * 9 / 5 + 32;
celsius.value = round2(c).toFixed(2);
fahrenheit.value = round2(f).toFixed(2);
}
updating = false;
}
celsius.addEventListener("input", function () {
updateFrom(celsius);
});
fahrenheit.addEventListener("input", function () {
updateFrom(fahrenheit);
});
kelvin.addEventListener("input", function () {
updateFrom(kelvin);
});
setValues(, 32, 273.15);
}());
</script>
</body>
</html>
openaigpt-5.5-pro
9.8/10142.7 s
openaigpt-5.5-pro
Tokens1 203
Code source3.2 KB
Temps142.7 s
Jugement Matania
Rendering
9
UX
10
Qualité du code
9
Complétude
10
Fidélité
10
Global
9.75
Revue
Le modèle a parfaitement respecté toutes les contraintes techniques et esthétiques. L'interface est propre, centrée et respecte le format 400x400. La logique de conversion est fluide, précise et l'implémentation du mode 'live' est robuste grâce à la gestion de l'état d'update pour éviter les boucles infinies.
Le modèle respecte presque toutes les contraintes, y compris la zone 400x400 et la mise à jour en direct. L'esthétique est propre et fonctionnelle. Cependant, le code source est mal formé car il manque la balise d'ouverture <html> et <head>, ce qui est une erreur de structure pour un 'HTML autonome', bien que le rendu soit correct.
Le code est gravement corrompu : de nombreuses valeurs CSS et JavaScript sont vides ou mal formées (ex: margin:;, rgba(,,,.2), || ;), ce qui rend le rendu visuel cassé et le script totalement inopérant. La logique de conversion est également erronée car elle repose sur une variable 'c' mal gérée dans la fonction updateAll, empêchant la mise à jour live demandée. Le modèle a échoué sur presque toutes les contraintes techniques et fonctionnelles.
Le code est totalement corrompu : de nombreuses valeurs CSS sont vides ou mal formées (ex: 'margin: ;', 'background: #ff2f5;', 'rgba(,,,.12)'), ce qui empêche un rendu correct. La fidélité est catastrophique car le modèle n'a pas respecté la syntaxe de base du langage, rendant le fichier HTML/CSS invalide et non fonctionnel visuellement malgré une logique JS cohérente.
Le modèle a parfaitement respecté toutes les contraintes, y compris la zone de 400x400 et la logique d'harmonie des couleurs. Le code est propre, bien structuré, et l'expérience utilisateur est fluide avec un feedback visuel efficace lors de la copie. Seul un léger bémol sur la structure HTML (balise </head> et <body> orphelines car le <head> n'est pas ouvert explicitement) est à noter, mais cela n'affecte pas le rendu.
Le rendu visuel est excellent et l'UX est très soignée avec des animations fluides. Cependant, le code est incomplet (tronqué à la fin de la fonction renderPalette), ce qui empêche l'exécution réelle de la fonctionnalité de copie et de régénération. La fidélité est pénalisée car le modèle n'a pas fourni le code complet demandé, rendant l'outil partiellement inopérant.
Le modèle a parfaitement respecté toutes les contraintes, y compris les dimensions de la zone et le mode de génération de palettes cohérentes. Le rendu est esthétique avec un bon contraste pour les codes hexadécimaux, et l'implémentation du feedback (toast) et de la copie est fluide et fonctionnelle.
<style>
body { margin: 0; font-family: Arial, sans-serif; background: #1e1e1e; display: flex; align-items: center; justify-content: center; min-height: 100vh; }
.app { width: 400px; height: 400px; background: #2a2a2a; border-radius: 8px; padding: 10px; box-sizing: border-box; display: flex; flex-direction: column; position: relative; }
.palette { flex: 1; display: flex; gap: 6px; }
.swatch { flex: 1; border-radius: 6px; cursor: pointer; display: flex; align-items: flex-end; justify-content: center; padding-bottom: 8px; transition: transform 0.15s; box-shadow: 0 2px 6px rgba(0,0,0,0.4); }
.swatch:hover { transform: translateY(-3px); }
.hex { background: rgba(0,0,0,0.55); color: #fff; font-size: 11px; padding: 3px 6px; border-radius: 3px; font-family: monospace; letter-spacing: 0.5px; }
.btn { margin-top: 10px; padding: 10px; background: #4a90e2; color: #fff; border: none; border-radius: 6px; font-size: 14px; cursor: pointer; font-weight: bold; }
.btn:hover { background: #5aa0f2; }
.toast { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(0,0,0,0.85); color: #fff; padding: 10px 20px; border-radius: 6px; opacity: 0; transition: opacity 0.3s; pointer-events: none; font-size: 14px; }
.toast.show { opacity: 1; }
</style>
</head>
<body>
<div class="app">
<div class="palette" id="palette"></div>
<button class="btn" id="regen">Régénérer</button>
<div class="toast" id="toast">Copié !</div>
</div>
<script>
function hslToHex(h, s, l) {
s /= 100; l /= 100;
var c = (1 - Math.abs(2 * l - 1)) * s;
var x = c * (1 - Math.abs(((h / 60) % 2) - 1));
var m = l - c / 2;
var r = 0, g = 0, b = 0;
if (h < 60) { r = c; g = x; b = 0; }
else if (h < 120) { r = x; g = c; b = 0; }
else if (h < 180) { r = 0; g = c; b = x; }
else if (h < 240) { r = 0; g = x; b = c; }
else if (h < 300) { r = x; g = 0; b = c; }
else { r = c; g = 0; b = x; }
var toHex = function(v) {
var h = Math.round((v + m) * 255).toString(16);
return h.length === 1 ? '0' + h : h;
};
return '#' + toHex(r) + toHex(g) + toHex(b);
}
function generatePalette() {
var base = Math.floor(Math.random() * 360);
var mode = Math.floor(Math.random() * 3);
var hues;
if (mode === 0) {
hues = [base, base, base, base, base];
} else if (mode === 1) {
hues = [base, base, base, (base + 180) % 360, (base + 180) % 360];
} else {
hues = [base, (base + 30) % 360, (base + 60) % 360, (base + 90) % 360, (base + 120) % 360];
}
var sats = [70, 65, 60, 55, 50];
var lights = [30, 45, 55, 65, 75];
var colors = [];
for (var i = 0; i < 5; i++) {
colors.push(hslToHex(hues[i], sats[i], lights[i]));
}
return colors;
}
function getTextColor(hex) {
var r = parseInt(hex.substr(1, 2), 16);
var g = parseInt(hex.substr(3, 2), 16);
var b = parseInt(hex.substr(5, 2), 16);
return (r * 299 + g * 587 + b * 114) / 1000 > 128 ? '#000' : '#fff';
}
function showToast() {
var t = document.getElementById('toast');
t.classList.add('show');
setTimeout(function() { t.classList.remove('show'); }, 1000);
}
function render() {
var colors = generatePalette();
var pal = document.getElementById('palette');
pal.innerHTML = '';
colors.forEach(function(c) {
var div = document.createElement('div');
div.className = 'swatch';
div.style.background = c;
var label = document.createElement('span');
label.className = 'hex';
label.textContent = c.toUpperCase();
div.appendChild(label);
div.addEventListener('click', function() {
if (navigator.clipboard) {
navigator.clipboard.writeText(c.toUpperCase());
}
showToast();
});
pal.appendChild(div);
});
}
document.getElementById('regen').addEventListener('click', render);
render();
</script>
</body>
</html>
anthropicclaude-sonnet-4-6
5.6/1031.0 s
anthropicclaude-sonnet-4-6
Tokens3 152
Code source6.8 KB
Temps31.0 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
7
Complétude
4
Fidélité
4
Global
5.63
Revue
Le modèle a produit un code incomplet (tronqué à la fin du script), ce qui empêche l'exécution réelle de la totalité des fonctionnalités comme la boucle de rendu ou l'événement de clic pour la copie. Bien que l'esthétique visuelle et la logique de génération de couleurs soient excellentes, la rupture brutale du code est une faute majeure de fidélité technique.
Le modèle a parfaitement respecté toutes les contraintes techniques, y compris la zone de 400x400 et l'algorithme de génération de couleurs cohérentes. L'interface est propre, le feedback de copie est bien présent et le code est bien structuré, bien qu'il utilise une méthode de copie un peu datée (execCommand) au lieu de l'API moderne demandée, mais cela fonctionne parfaitement.
<style>
body { margin: 0; padding: 0; font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background: #f0f0f0; }
#app { width: 400px; height: 400px; background: #fff; box-shadow: 0 4px 10px rgba(0,0,0,0.1); display: flex; flex-direction: column; position: relative; overflow: hidden; }
#palette { display: flex; flex: 1; width: 100%; height: 300px; }
.swatch { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; cursor: pointer; transition: transform 0.1s; position: relative; }
.swatch:hover { opacity: 0.9; }
.swatch:active { transform: scale(0.98); }
.hex-label { background: rgba(255,255,255,0.9); width: 100%; text-align: center; padding: 10px 0; font-size: 12px; font-weight: bold; color: #333; border-top: 1px solid rgba(0,0,0,0.05); }
#controls { height: 60px; display: flex; justify-content: center; align-items: center; background: #fff; }
button { padding: 10px 20px; font-size: 14px; cursor: pointer; background: #333; color: #fff; border: none; border-radius: 4px; }
button:hover { background: #555; }
#toast { position: absolute; top: 20px; left: 50%; transform: translateX(-50%); background: rgba(0,0,0,0.8); color: #fff; padding: 5px 15px; border-radius: 20px; font-size: 12px; opacity: 0; transition: opacity 0.3s; pointer-events: none; }
</style>
</head>
<body>
<div id="app">
<div id="toast">Copié !</div>
<div id="palette"></div>
<div id="controls">
<button id="refresh">Régénérer</button>
</div>
</div>
<script>
function hslToHex(h, s, l) {
l /= 100;
var a = s * Math.min(l, 1 - l) / 100;
var f = function(n) {
var k = (n + h / 30) % 12;
var color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return Math.round(255 * color).toString(16).padStart(2, "0");
};
return "#" + f(0) + f(8) + f(4);
}
function generate() {
var palette = document.getElementById("palette");
palette.innerHTML = "";
var baseHue = Math.floor(Math.random() * 360);
var baseSat = 40 + Math.floor(Math.random() * 40);
var baseLight = 30 + Math.floor(Math.random() * 40);
for (var i = 0; i < 5; i++) {
var h = (baseHue + (i * 20)) % 360;
var s = baseSat;
var l = baseLight + (i * 5);
if (l > 90) l = 90;
var hex = hslToHex(h, s, l);
var swatch = document.createElement("div");
swatch.className = "swatch";
swatch.style.backgroundColor = hex;
swatch.setAttribute("data-hex", hex);
var label = document.createElement("div");
label.className = "hex-label";
label.innerText = hex.toUpperCase();
swatch.appendChild(label);
swatch.onclick = function() {
var color = this.getAttribute("data-hex");
copyToClipboard(color);
};
palette.appendChild(swatch);
}
}
function copyToClipboard(text) {
var el = document.createElement("textarea");
el.value = text;
document.body.appendChild(el);
el.select();
document.execCommand("copy");
document.body.removeChild(el);
var toast = document.getElementById("toast");
toast.style.opacity = "1";
setTimeout(function() {
toast.style.opacity = "0";
}, 1000);
}
document.getElementById("refresh").onclick = generate;
generate();
</script>
</body>
</html>
googlegemini-flash-lite-latest
8.9/103.5 s
googlegemini-flash-lite-latest
Tokens1 138
Code source1.9 KB
Temps3.5 s
Jugement Matania
Rendering
8
UX
9
Qualité du code
8
Complétude
10
Fidélité
9
Global
8.88
Revue
Le modèle respecte presque toutes les contraintes, y compris la logique de cohérence des couleurs via le HSL. Le rendu est propre et l'UX est fluide avec le feedback de copie. Un léger bémol sur la contrainte de la zone 400x400 qui est partiellement respectée pour la palette mais pas pour l'ensemble du conteneur global, et le code HTML est légèrement mal formé (balise </head> orpheline).
<style>
body { margin: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; font-family: sans-serif; }
#palette { display: flex; width: 400px; height: 300px; }
.swatch { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; cursor: pointer; padding-bottom: 20px; transition: transform 0.1s; }
.swatch:hover { transform: scale(1.02); }
.hex { background: #fff; padding: 4px; font-size: 12px; font-weight: bold; border-radius: 4px; }
#btn { margin-top: 20px; padding: 10px 20px; cursor: pointer; }
#msg { height: 20px; color: green; font-weight: bold; }
</style>
</head>
<body>
<div id="palette"></div>
<div id="msg"></div>
<button id="btn" onclick="generate()">Régénérer</button>
<script>
function generate() {
var baseHue = Math.floor(Math.random() * 360);
var container = document.getElementById('palette');
container.innerHTML = '';
for (var i = 0; i < 5; i++) {
var s = 60 + Math.random() * 20;
var l = 30 + (i * 10);
var color = 'hsl(' + baseHue + ',' + s + '%,' + l + '%)';
var hex = hslToHex(baseHue, s, l);
var div = document.createElement('div');
div.className = 'swatch';
div.style.backgroundColor = color;
div.innerHTML = '<span class="hex">' + hex + '</span>';
div.onclick = (function(h) { return function() {
navigator.clipboard.writeText(h);
var m = document.getElementById('msg');
m.innerText = 'Copié ! ' + h;
setTimeout(function() { m.innerText = ''; }, 1000);
};})(hex);
container.appendChild(div);
}
}
function hslToHex(h, s, l) {
l /= 100;
var a = s * Math.min(l, 1 - l) / 100;
var f = function(n) {
var k = (n + h / 30) % 12;
var color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return Math.round(255 * color).toString(16).padStart(2, '0');
};
return '#' + f(0) + f(8) + f(4);
}
generate();
</script>
</body>
</html>
mistralmistral-large-latest
9.6/1015.5 s
mistralmistral-large-latest
Tokens1 236
Code source3.3 KB
Temps15.5 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
9
Complétude
10
Fidélité
10
Global
9.63
Revue
Le modèle a parfaitement respecté toutes les contraintes techniques et fonctionnelles du prompt. L'algorithme de génération de couleurs assure une réelle harmonie visuelle, et l'implémentation du copier-coller avec feedback est fluide. Le code est propre, autonome et respecte strictement le format de sortie demandé.
Le modèle a échoué sur la contrainte technique majeure : le code est tronqué à la fin (la fonction copyColor n'est pas terminée), ce qui rend l'application non fonctionnelle (le bouton de copie et la logique de génération sont brisés). Bien que le rendu visuel soit propre et respecte les consignes esthétiques, l'absence de code complet pour une tâche de génération de code est une erreur critique de fidélité.
Le modèle respecte presque toutes les instructions, y compris la logique d'harmonie et le feedback de copie. Cependant, il y a une erreur technique majeure dans la fonction `rgbToHex` qui tente de traiter une chaîne HSL comme si c'était du RGB (match sur des chiffres), ce qui risque de produire des codes hexadécimaux erronés ou de faire planter le script. De plus, la contrainte de zone '400x400' est respectée visuellement mais le code contient une balise de fermeture </head> orpheline sans <head> ouvert.
<style>
body{margin:0;padding:0;font-family:Arial,sans-serif;background:#f5f5f5;display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh}
.container{display:flex;flex-direction:column;align-items:center}
.palette{display:flex;width:100%;max-width:400px;margin-bottom:20px}
.color-box{flex:1;height:300px;border:1px solid #ddd;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center}
.color-box:hover{transform:scale(1.02)}
.hex{margin-top:10px;font-size:14px;font-weight:bold}
button{padding:10px 20px;font-size:16px;background:#4CAF50;color:white;border:none;border-radius:4px;cursor:pointer}
button:hover{background:#45a049}
.tooltip{position:fixed;bottom:20px;background:#333;color:#fff;padding:8px 16px;border-radius:4px;font-size:14px;opacity:0;transition:opacity 0.3s}
</style>
</head>
<body>
<div class="container">
<div class="palette" id="palette"></div>
<button id="regenerate">Régénérer</button>
<div class="tooltip" id="tooltip"></div>
</div>
<script>
var paletteEl = document.getElementById('palette');
var regenerateBtn = document.getElementById('regenerate');
var tooltip = document.getElementById('tooltip');
var baseHue = Math.floor(Math.random() * 360);
function generatePalette() {
paletteEl.innerHTML = '';
var colors = [];
for (var i = 0; i < 5; i++) {
var hue = (baseHue + i * 15) % 360;
var saturation = 70 + Math.floor(Math.random() * 20);
var lightness = 50 + Math.floor(Math.random() * 20);
var color = 'hsl(' + hue + ',' + saturation + '%,' + lightness + '%)';
colors.push(color);
var box = document.createElement('div');
box.className = 'color-box';
box.style.backgroundColor = color;
box.innerHTML = '<div class="hex">' + rgbToHex(color) + '</div>';
box.onclick = function() {
var hex = this.querySelector('.hex').textContent;
navigator.clipboard.writeText(hex).then(function() {
tooltip.textContent = 'Copié !';
tooltip.style.opacity = '1';
setTimeout(function() {
tooltip.style.opacity = '0';
}, 1000);
});
};
paletteEl.appendChild(box);
}
}
function rgbToHex(color) {
var rgb = color.match(/\d+/g);
var r = parseInt(rgb[0]).toString(16).padStart(2, '0');
var g = parseInt(rgb[1]).toString(16).padStart(2, '0');
var b = parseInt(rgb[2]).toString(16).padStart(2, '0');
return '#' + r + g + b;
}
regenerateBtn.onclick = function() {
baseHue = Math.floor(Math.random() * 360);
generatePalette();
};
generatePalette();
</script>
</body>
</
openaigpt-4o-mini
6.9/1014.3 s
openaigpt-4o-mini
Tokens1 151
Code source2.8 KB
Temps14.3 s
Jugement Matania
Rendering
7
UX
8
Qualité du code
7
Complétude
9
Fidélité
6
Global
6.88
Revue
Le modèle respecte la plupart des fonctionnalités (copie, régénération, affichage hex), mais échoue sur la contrainte de zone 400x400 en utilisant un layout plein écran (100vh). L'algorithme de génération de couleurs est très basique et ne garantit pas toujours une bonne lisibilité du texte blanc sur les couleurs claires, bien que le code soit fonctionnel et propre.
Le modèle a parfaitement respecté toutes les contraintes, y compris la zone de 400x400 et la logique d'harmonie des couleurs (analogues ou complémentaires). L'implémentation du copier-coller avec feedback visuel est robuste et le code est propre, bien structuré et autonome.
<style>
html, body {
margin: 0;
padding: 0;
width: 400px;
height: 400px;
overflow: hidden;
background: #f4f4f6;
font-family: Arial, sans-serif;
}
.container {
width: 400px;
height: 400px;
box-sizing: border-box;
padding: 16px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.palette {
width: 100%;
height: 320px;
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 8px;
}
.swatch-wrap {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
}
.swatch {
width: 100%;
height: 270px;
border-radius: 12px;
cursor: pointer;
position: relative;
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
border: 1px solid rgba(0,0,0,0.08);
}
.hex {
margin-top: 8px;
font-size: 13px;
font-weight: bold;
color: #222;
background: #ffffff;
padding: 4px 6px;
border-radius: 6px;
line-height: 1;
}
.copied {
position: absolute;
left: 50%;
top: 12px;
transform: translateX(-50%);
background: rgba(0,0,0,0.72);
color: #ffffff;
padding: 5px 8px;
border-radius: 10px;
font-size: 12px;
opacity: 0;
pointer-events: none;
}
.copied.show {
opacity: 1;
}
.controls {
width: 100%;
display: flex;
justify-content: center;
}
button {
width: 180px;
height: 40px;
border: 0;
border-radius: 20px;
background: #222;
color: #ffffff;
font-size: 15px;
font-weight: bold;
cursor: pointer;
}
button:hover {
background: #000000;
}
</style>
</head>
<body>
<div class="container">
<div class="palette" id="palette"></div>
<div class="controls">
<button id="regen">Régénérer</button>
</div>
</div>
<script>
(function () {
var paletteEl = document.getElementById('palette');
var regenBtn = document.getElementById('regen');
function rand(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function hslToHex(h, s, l) {
s = s / 100;
l = l / 100;
var c = (1 - Math.abs(2 * l - 1)) * s;
var x = c * (1 - Math.abs((h / 60) % 2 - 1));
var m = l - c / 2;
var r = 0;
var g = 0;
var b = 0;
if (0 <= h && h < 60) {
r = c; g = x; b = 0;
} else if (60 <= h && h < 120) {
r = x; g = c; b = 0;
} else if (120 <= h && h < 180) {
r = 0; g = c; b = x;
} else if (180 <= h && h < 240) {
r = 0; g = x; b = c;
} else if (240 <= h && h < 300) {
r = x; g = 0; b = c;
} else {
r = c; g = 0; b = x;
}
var rr = Math.round((r + m) * 255);
var gg = Math.round((g + m) * 255);
var bb = Math.round((b + m) * 255);
return "#" + toHex(rr) + toHex(gg) + toHex(bb);
}
function toHex(n) {
var hex = n.toString(16).toUpperCase();
return hex.length === 1 ? "0" + hex : hex;
}
function luminanceFromHex(hex) {
var r = parseInt(hex.substr(1, 2), 16);
var g = parseInt(hex.substr(3, 2), 16);
var b = parseInt(hex.substr(5, 2), 16);
return 0.299 * r + 0.587 * g + 0.114 * b;
}
function generatePalette() {
var mode = Math.random() < 0.5 ? "analogous" : "complementary";
var baseHue = rand(0, 359);
var colors = [];
var i;
if (mode === "analogous") {
var offsets = [-24, -12, 0, 12, 24];
for (i = 0; i < 5; i++) {
colors.push(hslToHex(
(baseHue + offsets[i] + 360) % 360,
rand(55, 80),
rand(40, 68)
));
}
} else {
var comp = (baseHue + 180) % 360;
colors.push(hslToHex(baseHue, rand(60, 80), 42));
colors.push(hslToHex(baseHue, rand(55, 75), 56));
colors.push(hslToHex(baseHue, rand(45, 65), 70));
colors.push(hslToHex(comp, rand(55, 75), 56));
colors.push(hslToHex(comp, rand(60, 80), 42));
}
return colors;
}
function copyText(text, popup) {
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(function () {
showCopied(popup);
}, function () {
fallbackCopy(text, popup);
});
} else {
fallbackCopy(text, popup);
}
}
function fallbackCopy(text, popup) {
var ta = document.createElement('textarea');
ta.value = text;
document.body.appendChild(ta);
ta.select();
try {
document.execCommand('copy');
} catch (e) {
}
document.body.removeChild(ta);
showCopied(popup);
}
function showCopied(el) {
el.className = 'copied show';
clearTimeout(el._timer);
el._timer = setTimeout(function () {
el.className = 'copied';
}, 900);
}
function render() {
var colors = generatePalette();
paletteEl.innerHTML = '';
for (var i = 0; i < colors.length; i++) {
var wrap = document.createElement('div');
wrap.className = 'swatch-wrap';
var swatch = document.createElement('div');
swatch.className = 'swatch';
swatch.style.background = colors[i];
var copied = document.createElement('div');
copied.className = 'copied';
copied.innerHTML = 'Copié !';
var hex = document.createElement('div');
hex.className = 'hex';
hex.innerHTML = colors[i];
hex.style.color = luminanceFromHex(colors[i]) < 110 ? '#111' : '#222';
swatch.appendChild(copied);
(function (value, popup) {
swatch.addEventListener('click', function () {
copyText(value, popup);
});
})(colors[i], copied);
wrap.appendChild(swatch);
wrap.appendChild(hex);
paletteEl.appendChild(wrap);
}
}
regenBtn.addEventListener('click', render);
render();
})();
</script>
</body>
</html>
openaigpt-5.4-mini
9.6/1011.3 s
openaigpt-5.4-mini
Tokens1 889
Code source5.7 KB
Temps11.3 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
9
Complétude
10
Fidélité
10
Global
9.63
Revue
Le modèle a parfaitement respecté toutes les contraintes, y compris la zone de 400x400 et le format de sortie brut. L'algorithme de génération de couleurs (analogues ou complémentaires) est bien implémenté, offrant une réelle cohérence visuelle. L'interface est propre, moderne et l'expérience de copie avec le feedback 'Copié !' est fluide et intuitive.
<style>
html, body {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
background: #f3f4f6;
font-family: Arial, Helvetica, sans-serif;
}
.app {
width: 400px;
height: 400px;
margin: 0 auto;
position: relative;
background: #f3f4f6;
box-sizing: border-box;
padding: 12px;
}
.palette {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 8px;
height: 320px;
align-items: stretch;
}
.swatchWrap {
display: flex;
flex-direction: column;
height: 100%;
min-width: 0;
}
.swatch {
flex: 1;
border-radius: 12px;
cursor: pointer;
position: relative;
box-shadow: 0 4px 10px rgba(0,0,0,0.12);
border: 2px solid rgba(255,255,255,0.65);
transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.swatch:hover {
transform: translateY(-2px);
box-shadow: 0 7px 14px rgba(0,0,0,0.16);
}
.hex {
margin-top: 6px;
text-align: center;
font-size: 12px;
font-weight: bold;
color: #111827;
background: rgba(255,255,255,0.72);
border-radius: 8px;
padding: 4px 2px;
user-select: none;
}
.controls {
position: absolute;
left: 12px;
right: 12px;
bottom: 12px;
display: flex;
justify-content: center;
align-items: center;
}
button {
border: none;
border-radius: 999px;
padding: 12px 18px;
font-size: 14px;
font-weight: bold;
background: #111827;
color: #ffffff;
cursor: pointer;
box-shadow: 0 4px 10px rgba(0,0,0,0.16);
}
button:hover {
background: #1f2937;
}
.toast {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background: rgba(17, 24, 39, 0.92);
color: #ffffff;
padding: 8px 12px;
border-radius: 999px;
font-size: 13px;
font-weight: bold;
pointer-events: none;
opacity: 0;
transition: opacity 0.2s ease, transform 0.2s ease;
z-index: 10;
}
.toast.show {
opacity: 1;
transform: translate(-50%, -55%);
}
</style>
</head>
<body>
<div class="app">
<div id="toast" class="toast">Copié !</div>
<div id="palette" class="palette"></div>
<div class="controls">
<button id="regen">Régénérer</button>
</div>
</div>
<script>
(function () {
var palette = document.getElementById('palette');
var regen = document.getElementById('regen');
var toast = document.getElementById('toast');
var toastTimer = null;
function rand(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function clamp(v, min, max) {
return Math.max(min, Math.min(max, v));
}
function hslToHex(h, s, l) {
h = h % 360;
s = s / 100;
l = l / 100;
var c = (1 - Math.abs(2 * l - 1)) * s;
var x = c * (1 - Math.abs((h / 60) % 2 - 1));
var m = l - c / 2;
var r = 0, g = 0, b = 0;
if (h < 60) {
r = c; g = x; b = 0;
} else if (h < 120) {
r = x; g = c; b = 0;
} else if (h < 180) {
r = 0; g = c; b = x;
} else if (h < 240) {
r = 0; g = x; b = c;
} else if (h < 300) {
r = x; g = 0; b = c;
} else {
r = c; g = 0; b = x;
}
function toHex(n) {
var v = Math.round((n + m) * 255);
var s2 = v.toString(16);
return s2.length === 1 ? '0' + s2 : s2;
}
return '#' + toHex(r) + toHex(g) + toHex(b);
}
function showToast() {
toast.className = 'toast show';
if (toastTimer) {
clearTimeout(toastTimer);
}
toastTimer = setTimeout(function () {
toast.className = 'toast';
}, 900);
}
function copyText(text) {
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(function () {
showToast();
}).catch(function () {
showToast();
});
} else {
var ta = document.createElement('textarea');
ta.value = text;
document.body.appendChild(ta);
ta.select();
try {
document.execCommand('copy');
} catch (e) {}
document.body.removeChild(ta);
showToast();
}
}
function generatePalette() {
var scheme = Math.random() < 0.6 ? 'analogous' : 'complementary';
var baseHue = rand(0, 359);
var colors = [];
var i;
if (scheme === 'analogous') {
var offsets = [-24, -12, 0, 12, 24];
var baseSat = rand(55, 85);
var baseLum = rand(42, 68);
for (i = 0; i < 5; i++) {
var h = (baseHue + offsets[i]) % 360;
var s = clamp(baseSat + rand(-10, 10), 35, 90);
var l = clamp(baseLum + rand(-10, 10), 28, 82);
colors.push(hslToHex(h, s, l));
}
} else {
var compHue = (baseHue + 180) % 360;
var hues = [baseHue - 12, baseHue + 8, baseHue, compHue - 8, compHue + 12];
for (i = 0; i < 5; i++) {
var hh = (hues[i] + 360) % 360;
var ss = i < 3 ? rand(50, 82) : rand(45, 78);
var ll = i === 2 ? rand(40, 62) : rand(48, 72);
colors.push(hslToHex(hh, ss, ll));
}
}
palette.innerHTML = '';
for (i = 0; i < 5; i++) {
(function (hex) {
var wrap = document.createElement('div');
wrap.className = 'swatchWrap';
var swatch = document.createElement('div');
swatch.className = 'swatch';
swatch.style.background = hex;
swatch.setAttribute('data-hex', hex);
var label = document.createElement('div');
label.className = 'hex';
label.textContent = hex.toUpperCase();
swatch.addEventListener('click', function () {
copyText(this.getAttribute('data-hex'));
});
wrap.appendChild(swatch);
wrap.appendChild(label);
palette.appendChild(wrap);
})(colors[i]);
}
}
regen.addEventListener('click', generatePalette);
generatePalette();
})();
</script>
</body>
</html>
openaigpt-5.4-nano
4.3/1021.2 s
openaigpt-5.4-nano
Tokens2 886
Code source9.6 KB
Temps21.2 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
6
Complétude
2
Fidélité
2
Global
4.25
Revue
Le modèle a échoué de manière critique sur la complétude et la fidélité car le code est tronqué (il s'arrête brusquement au milieu d'une boucle dans la fonction JavaScript). Bien que le style CSS et la structure HTML soient excellents et prometteurs pour le rendu visuel, l'application est totalement non fonctionnelle car le script est incomplet.
Le modèle a généré un code de très haute qualité visuelle et logique, mais il a été coupé brusquement avant la fin du script (le code s'arrête au milieu d'une boucle). En conséquence, la fonctionnalité de génération et de copie ne peut pas fonctionner, ce qui entraîne une note de complétude et de fidélité extrêmement basse malgré l'intention manifeste de respecter toutes les règles.
Le modèle a parfaitement respecté toutes les contraintes, y compris la zone de 400x400 et l'algorithme de génération de palettes cohérentes. L'interface est esthétique, le code est propre et l'expérience utilisateur (feedback de copie, effets de survol) est excellente.
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
background: #f2f2f2;
font-family: Arial, sans-serif;
}
#app {
width: 400px;
height: 400px;
box-sizing: border-box;
padding: 16px;
background: #ffffff;
display: flex;
flex-direction: column;
gap: 12px;
position: relative;
overflow: hidden;
}
#palette {
flex: 1;
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 8px;
min-height: 0;
}
.swatchWrap {
display: flex;
flex-direction: column;
min-width: 0;
gap: 8px;
}
.swatch {
flex: 1;
border-radius: 14px;
cursor: pointer;
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.12);
transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.swatch:hover {
transform: translateY(-2px);
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.16), 0 8px 16px rgba(0,0,0,0.14);
}
.hex {
height: 24px;
line-height: 24px;
text-align: center;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.4px;
color: #222222;
background: #f4f4f4;
border-radius: 8px;
user-select: all;
}
#regen {
height: 44px;
border: 0;
border-radius: 12px;
background: #222222;
color: #ffffff;
font-size: 16px;
font-weight: 700;
cursor: pointer;
}
#regen:hover {
background: #000000;
}
#copied {
position: absolute;
left: 50%;
bottom: 72px;
transform: translateX(-50%);
padding: 8px 14px;
border-radius: 999px;
background: rgba(0,0,0,0.82);
color: #ffffff;
font-size: 14px;
font-weight: 700;
opacity: 0;
pointer-events: none;
transition: opacity 0.18s ease;
}
#copied.show {
opacity: 1;
}
</style>
</head>
<body>
<div id="app">
<div id="palette"></div>
<button id="regen" type="button">Régénérer</button>
<div id="copied">Copié !</div>
</div>
<script>
(function () {
var palette = document.getElementById("palette");
var regen = document.getElementById("regen");
var copied = document.getElementById("copied");
var timer = null;
function clamp(v, min, max) {
return Math.max(min, Math.min(max, v));
}
function padHex(n) {
var s = n.toString(16).toUpperCase();
return s.length === 1 ? "0" + s : s;
}
function hslToHex(h, s, l) {
h = ((h % 360) + 360) % 360;
s = clamp(s, 0, 100) / 100;
l = clamp(l, 0, 100) / 100;
var c = (1 - Math.abs(2 * l - 1)) * s;
var x = c * (1 - Math.abs((h / 60) % 2 - 1));
var m = l - c / 2;
var r = 0;
var g = 0;
var b = 0;
if (h < 60) {
r = c; g = x; b = 0;
} else if (h < 120) {
r = x; g = c; b = 0;
} else if (h < 180) {
r = 0; g = c; b = x;
} else if (h < 240) {
r = 0; g = x; b = c;
} else if (h < 300) {
r = x; g = 0; b = c;
} else {
r = c; g = 0; b = x;
}
r = Math.round((r + m) * 255);
g = Math.round((g + m) * 255);
b = Math.round((b + m) * 255);
return "#" + padHex(r) + padHex(g) + padHex(b);
}
function makePalette() {
var base = Math.floor(Math.random() * 360);
var mode = Math.floor(Math.random() * 3);
var colors = [];
var i;
var h;
var s;
var l;
var offsets;
if (mode === 0) {
offsets = [-32, -16, 0, 16, 32];
for (i = 0; i < 5; i++) {
h = base + offsets[i];
s = 58 + Math.floor(Math.random() * 18);
l = 40 + i * 6 + Math.floor(Math.random() * 5);
colors.push(hslToHex(h, s, l));
}
} else if (mode === 1) {
offsets = [0, 12, -12, 180, 192];
for (i = 0; i < 5; i++) {
h = base + offsets[i];
s = 54 + Math.floor(Math.random() * 22);
l = 42 + Math.floor(Math.random() * 22);
colors.push(hslToHex(h, s, l));
}
} else {
offsets = [0, 0, 0, 0, 0];
for (i = 0; i < 5; i++) {
h = base;
s = 48 + i * 8;
l = 28 + i * 11;
colors.push(hslToHex(h, s, l));
}
}
return colors;
}
function showCopied() {
if (timer) {
clearTimeout(timer);
}
copied.className = "show";
timer = setTimeout(function () {
copied.className = "";
}, 900);
}
function copyHex(hex) {
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(hex).then(function () {
showCopied();
}, function () {
showCopied();
});
} else {
showCopied();
}
}
function render() {
var colors = makePalette();
var html = "";
var i;
for (i = 0; i < colors.length; i++) {
html += '<div class="swatchWrap">';
html += '<div class="swatch" data-hex="' + colors[i] + '" style="background:' + colors[i] + '"></div>';
html += '<div class="hex">' + colors[i] + '</div>';
html += '</div>';
}
palette.innerHTML = html;
var swatches = palette.getElementsByClassName("swatch");
for (i = 0; i < swatches.length; i++) {
swatches[i].onclick = function () {
copyHex(this.getAttribute("data-hex"));
};
}
}
regen.onclick = render;
render();
}());
</script>
</body>
</html>
openaigpt-5.5-pro
6.8/10240.6 s
openaigpt-5.5-pro
Tokens2 404
Code source7.8 KB
Temps240.6 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
8
Complétude
4
Fidélité
6
Global
6.75
Revue
Le rendu visuel et l'UX sont excellents, avec un design moderne et des interactions bien pensées. Cependant, le code est tronqué à la fin du script (le fichier s'arrête brutalement au milieu d'une fonction), ce qui rend l'application totalement inopérante : le bouton de régénération et la fonction de copie ne fonctionnent pas. La fidélité est pénalisée par cette rupture technique majeure qui empêche la complétude de la tâche.
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #eef2f7;
font-family: Arial, Helvetica, sans-serif;
}
#app {
width: 400px;
height: 400px;
padding: 16px;
background: #ffffff;
border: 1px solid #d8dee8;
color: #111827;
display: flex;
flex-direction: column;
}
#title {
height: 26px;
margin: 0 0 10px 0;
font-size: 18px;
line-height: 26px;
font-weight: 800;
text-align: center;
}
#palette {
flex: 1;
min-height: 0;
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 8px;
margin-bottom: 12px;
}
.tile {
min-width: 0;
display: flex;
flex-direction: column;
position: relative;
}
.swatch {
flex: 1;
min-height: 0;
width: 100%;
border: 1px solid rgba(0, 0, 0, 0.12);
border-radius: 14px;
cursor: pointer;
position: relative;
padding: 0;
outline: none;
}
.swatch:focus {
border: 3px solid #111827;
}
.hex {
height: 30px;
display: flex;
align-items: center;
justify-content: center;
font-family: "Courier New", monospace;
font-size: 12px;
font-weight: 800;
color: #111827;
user-select: all;
}
.copied {
position: absolute;
left: 50%;
top: 10px;
transform: translateX(-50%);
padding: 5px 8px;
border-radius: 999px;
background: rgba(17, 24, 39, 0.92);
color: #ffffff;
font-size: 11px;
font-weight: 700;
opacity: 0;
pointer-events: none;
white-space: nowrap;
transition: opacity 0.15s ease;
}
.tile.show .copied {
opacity: 1;
}
#regen {
height: 44px;
width: 100%;
border: 0;
border-radius: 12px;
background: #111827;
color: #ffffff;
font-size: 16px;
font-weight: 800;
cursor: pointer;
}
#regen:active {
transform: translateY(1px);
}
</style>
</head>
<body>
<div id="app">
<h1 id="title">Palette harmonieuse</h1>
<div id="palette" aria-label="Palette générée">
<div class="tile"><button class="swatch" type="button" aria-label="Copier la couleur"><span class="copied">Copié !</span></button><div class="hex">#000000</div></div>
<div class="tile"><button class="swatch" type="button" aria-label="Copier la couleur"><span class="copied">Copié !</span></button><div class="hex">#000000</div></div>
<div class="tile"><button class="swatch" type="button" aria-label="Copier la couleur"><span class="copied">Copié !</span></button><div class="hex">#000000</div></div>
<div class="tile"><button class="swatch" type="button" aria-label="Copier la couleur"><span class="copied">Copié !</span></button><div class="hex">#000000</div></div>
<div class="tile"><button class="swatch" type="button" aria-label="Copier la couleur"><span class="copied">Copié !</span></button><div class="hex">#000000</div></div>
</div>
<button id="regen" type="button">Régénérer</button>
</div>
<script>
(function () {
var swatches = document.getElementsByClassName("swatch");
var hexes = document.getElementsByClassName("hex");
var tiles = document.getElementsByClassName("tile");
var regen = document.getElementById("regen");
var copyTimer = null;
function rand(min, max) {
return min + Math.random() * (max - min);
}
function randInt(min, max) {
return Math.floor(rand(min, max + 1));
}
function clamp(value, min, max) {
return Math.max(min, Math.min(max, value));
}
function mod(value, size) {
return ((value % size) + size) % size;
}
function hueToRgb(p, q, t) {
if (t < 0) {
t += 1;
}
if (t > 1) {
t -= 1;
}
if (t < 1 / 6) {
return p + (q - p) * 6 * t;
}
if (t < 1 / 2) {
return q;
}
if (t < 2 / 3) {
return p + (q - p) * (2 / 3 - t) * 6;
}
return p;
}
function hslToRgb(h, s, l) {
var r;
var g;
var b;
var p;
var q;
h = mod(h, 360) / 360;
s = s / 100;
l = l / 100;
if (s === 0) {
r = l;
g = l;
b = l;
} else {
q = l < 0.5 ? l * (1 + s) : l + s - l * s;
p = 2 * l - q;
r = hueToRgb(p, q, h + 1 / 3);
g = hueToRgb(p, q, h);
b = hueToRgb(p, q, h - 1 / 3);
}
return {
r: Math.round(r * 255),
g: Math.round(g * 255),
b: Math.round(b * 255)
};
}
function toHexByte(value) {
var text = value.toString(16).toUpperCase();
if (text.length < 2) {
text = "0" + text;
}
return text;
}
function hslToHex(h, s, l) {
var rgb = hslToRgb(h, s, l);
return "#" + toHexByte(rgb.r) + toHexByte(rgb.g) + toHexByte(rgb.b);
}
function buildPalette() {
var base = randInt(0, 359);
var scheme = randInt(0, 2);
var colors = [];
var offsets;
var lights;
var satBase;
var lightBase;
var i;
if (scheme === 0) {
offsets = [-34, -16, 0, 17, 36];
satBase = randInt(58, 80);
lightBase = randInt(42, 56);
for (i = 0; i < 5; i++) {
colors.push(hslToHex(base + offsets[i] + rand(-4, 4), clamp(satBase + rand(-8, 8), 45, 88), clamp(lightBase + (i - 2) * 5 + rand(-3, 3), 30, 74)));
}
} else if (scheme === 1) {
lights = [26, 38, 50, 62, 74];
satBase = randInt(55, 84);
for (i = 0; i < 5; i++) {
colors.push(hslToHex(base + rand(-5, 5), clamp(satBase + rand(-7, 7), 42, 90), clamp(lights[i] + rand(-3, 3), 22, 78)));
}
} else {
offsets = [-12, 0, 14, 166, 194];
lights = [36, 49, 62, 43, 58];
satBase = randInt(56, 82);
for (i = 0; i < 5; i++) {
colors.push(hslToHex(base + offsets[i] + rand(-3, 3), clamp(satBase + rand(-9, 9), 44, 90), clamp(lights[i] + rand(-4, 4), 30, 72)));
}
}
return colors;
}
function clearCopied() {
var i;
if (copyTimer) {
window.clearTimeout(copyTimer);
copyTimer = null;
}
for (i = 0; i < tiles.length; i++) {
tiles[i].className = "tile";
}
}
function showCopied(index) {
clearCopied();
tiles[index].className = "tile show";
copyTimer = window.setTimeout(function () {
tiles[index].className = "tile";
copyTimer = null;
}, 900);
}
function fallbackCopy(text) {
var area = document.createElement("textarea");
area.value = text;
area.setAttribute("readonly", "readonly");
area.style.position = "fixed";
area.style.left = "0";
area.style.top = "0";
area.style.opacity = "0";
document.body.appendChild(area);
area.focus();
area.select();
try {
document.execCommand("copy");
} catch (ignore) {
}
document.body.removeChild(area);
}
function copyHex(index) {
var hex = swatches[index].getAttribute("data-hex");
var promise;
if (navigator.clipboard && navigator.clipboard.writeText) {
try {
promise = navigator.clipboard.writeText(hex);
} catch (error) {
fallbackCopy(hex);
showCopied(index);
return;
}
if (promise && typeof promise.then === "function") {
promise.then(function () {
showCopied(index);
}, function () {
fallbackCopy(hex);
showCopied(index);
});
} else {
showCopied(index);
}
} else {
fallbackCopy(hex);
showCopied(index);
}
}
function render() {
var palette = buildPalette();
var i;
clearCopied();
for (i = 0; i < 5; i++) {
swatches[i].style.backgroundColor = palette[i];
swatches[i].setAttribute("data-hex", palette[i]);
swatches[i].setAttribute("aria-label", "Copier " + palette[i]);
hexes[i].textContent = palette[i];
}
}
function attachEvents() {
var i;
for (i = 0; i < swatches.length; i++) {
(function (index) {
swatches[index].addEventListener("click", function () {
copyHex(index);
});
}(i));
}
regen.addEventListener("click", render);
}
attachEvents();
render();
}());
</script>
</body>
</html>
productiviamatania-latest
9.5/1013.1 s
productiviamatania-latest
Tokens1 821
Code source5.5 KB
Temps13.1 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
8
Complétude
10
Fidélité
10
Global
9.5
Revue
Le modèle a parfaitement respecté toutes les contraintes du prompt, y compris la zone de 400x400 et l'algorithme de génération de palettes cohérentes. L'implémentation du contraste de texte (YIQ) pour la lisibilité des codes hexadécimaux est un excellent ajout technique. Le code est propre, autonome et fonctionnel.
<style>
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f0f0f0;
font-family: sans-serif;
}
#app {
width: 400px;
height: 400px;
background-color: #fff;
position: relative;
overflow: hidden;
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
}
#palette-container {
display: flex;
width: 100%;
height: 320px;
}
.color-column {
flex: 1;
height: 100%;
display: flex;
flex-direction: column;
cursor: pointer;
transition: transform 0.1s;
}
.color-column:active {
transform: scale(0.98);
}
.color-box {
flex: 1;
}
.color-label {
height: 40px;
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
font-weight: bold;
text-transform: uppercase;
}
#controls {
width: 100%;
height: 80px;
display: flex;
justify-content: center;
align-items: center;
background-color: #fff;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
background-color: #333;
color: #fff;
border: none;
border-radius: 4px;
}
button:hover {
background-color: #555;
}
#toast {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0,0,0,0.7);
color: #fff;
padding: 8px 16px;
border-radius: 20px;
font-size: 14px;
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
}
</style>
</head>
<body>
<div id="app">
<div id="palette-container"></div>
<div id="controls">
<button id="regen-btn">Régénérer</button>
</div>
<div id="toast">Copié !</div>
</div>
<script>
var container = document.getElementById('palette-container');
var btn = document.getElementById('regen-btn');
var toast = document.getElementById('toast');
function hslToHex(h, s, l) {
l /= 100;
var a = s * Math.min(l, 1 - l) / 100;
var f = function(n) {
var k = (n + h / 30) % 12;
var color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return Math.round(255 * color).toString(16).padStart(2, '0');
};
return '#' + f(0) + f(8) + f(4);
}
function generatePalette() {
container.innerHTML = '';
var baseHue = Math.floor(Math.random() * 360);
var mode = Math.floor(Math.random() * 3); // 0: Analogous, 1: Monochromatic, 2: Complementary
var colors = [];
for (var i = 0; i < 5; i++) {
var h, s, l;
if (mode === 0) { // Analogous
h = (baseHue + (i * 20 - 40) + 360) % 360;
s = 60 + Math.random() * 20;
l = 40 + Math.random() * 30;
} else if (mode === 1) { // Monochromatic
h = baseHue;
s = 30 + (i * 15);
l = 20 + (i * 15);
} else { // Complementary / Split
if (i < 3) {
h = baseHue;
s = 70;
l = 20 + (i * 25);
} else {
h = (baseHue + 180) % 360;
s = 70;
l = 20 + ((i-3) * 25);
}
}
colors.push(hslToHex(h, s, l));
}
for (var j = 0; j < colors.length; j++) {
var hex = colors[j];
var col = document.createElement('div');
col.className = 'color-column';
var box = document.createElement('div');
box.className = 'color-box';
box.style.backgroundColor = hex;
var label = document.createElement('div');
label.className = 'color-label';
label.innerText = hex;
label.style.color = getContrastYIQ(hex);
col.appendChild(box);
col.appendChild(label);
col.onclick = function() {
copyToClipboard(hex);
};
container.appendChild(col);
}
}
function getContrastYIQ(hexcolor){
hexcolor = hexcolor.replace("#", "");
var r = parseInt(hexcolor.substr(0,2),16);
var g = parseInt(hexcolor.substr(2,2),16);
var b = parseInt(hexcolor.substr(4,2),16);
var yiq = ((r*299)+(g*587)+(b*114))/1000;
return (yiq >= 128) ? 'black' : 'white';
}
function copyToClipboard(text) {
var dummy = document.createElement("textarea");
document.body.appendChild(dummy);
dummy.value = text;
dummy.select();
document.execCommand("copy");
document.body.removeChild(dummy);
toast.style.opacity = '1';
setTimeout(function() {
toast.style.opacity = '0';
}, 1000);
}
btn.onclick = generatePalette;
generatePalette();
</script>
</body>
</html>
xaigrok-4-1-fast-non-reasoning
7.4/1012.6 s
xaigrok-4-1-fast-non-reasoning
Tokens1 504
Code source4.4 KB
Temps12.6 s
Jugement Matania
Rendering
8
UX
9
Qualité du code
9
Complétude
9
Fidélité
6
Global
7.38
Revue
Le code est excellent, propre et fonctionnel avec une très bonne gestion de l'harmonie des couleurs et du feedback utilisateur (animation 'Copié !'). Cependant, le modèle a échoué sur une contrainte technique majeure du prompt : la zone doit être de 400x400, or le rendu utilise un layout flexible qui occupe toute la hauteur de la fenêtre (100vh) sans limite de dimensionnement.
<!DOCTYPE html>
<html>
<head>
<title>Générateur de Palette</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
background: #f0f0f0;
}
.palette {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.color-box {
width: 80px;
height: 80px;
border-radius: 8px;
cursor: pointer;
position: relative;
transition: transform 0.2s;
border: 2px solid #fff;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.color-box:hover {
transform: scale(1.05);
}
.color-box.copied::after {
content: "Copié !";
position: absolute;
top: -30px;
left: 50%;
transform: translateX(-50%);
background: #4CAF50;
color: white;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
animation: fade 1s ease-out forwards;
}
@keyframes fade {
0% { opacity: 1; transform: translateX(-50%) translateY(0); }
100% { opacity: 0; transform: translateX(-50%) translateY(-10px); }
}
.hex-code {
text-align: center;
font-family: monospace;
font-size: 12px;
margin-top: 4px;
font-weight: bold;
}
.generate-btn {
background: #2196F3;
color: white;
border: none;
padding: 12px 24px;
font-size: 16px;
border-radius: 25px;
cursor: pointer;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
transition: all 0.3s;
}
.generate-btn:hover {
background: #1976D2;
transform: translateY(-2px);
}
</style>
</head>
<body>
<div class="palette" id="palette"></div>
<button class="generate-btn" onclick="generatePalette()">Régénérer</button>
<script>
function hslToHex(h, s, l) {
var hue = h;
var sat = s / 100;
var lum = l / 100;
var c = (1 - Math.abs(2 * lum - 1)) * sat;
var x = c * (1 - Math.abs((hue / 60) % 2 - 1));
var m = lum - c / 2;
var r, g, b;
if (0 <= hue && hue < 60) { r = c; g = x; b = 0; }
else if (60 <= hue && hue < 120) { r = x; g = c; b = 0; }
else if (120 <= hue && hue < 180) { r = 0; g = c; b = x; }
else if (180 <= hue && hue < 240) { r = 0; g = x; b = c; }
else if (240 <= hue && hue < 300) { r = x; g = 0; b = c; }
else { r = c; g = 0; b = x; }
var R = Math.round((r + m) * 255);
var G = Math.round((g + m) * 255);
var B = Math.round((b + m) * 255);
return "#" + ((1 << 24) + (R << 16) + (G << 8) + B).toString(16).slice(1).toUpperCase();
}
function generatePalette() {
var baseHue = Math.random() * 360;
var colors = [];
// 5 couleurs harmonieuses : base + variations et complémentaire
colors.push({
hex: hslToHex(baseHue, 70 + Math.random() * 20, 50 + Math.random() * 10),
hsl: [baseHue, 70 + Math.random() * 20, 50 + Math.random() * 10]
});
colors.push({
hex: hslToHex((baseHue + 30) % 360, 60 + Math.random() * 20, 45 + Math.random() * 15),
hsl: [(baseHue + 30) % 360, 60 + Math.random() * 20, 45 + Math.random() * 15]
});
colors.push({
hex: hslToHex((baseHue + 60) % 360, 65 + Math.random() * 25, 55 + Math.random() * 10),
hsl: [(baseHue + 60) % 360, 65 + Math.random() * 25, 55 + Math.random() * 10]
});
var complementHue = (baseHue + 180) % 360;
colors.push({
hex: hslToHex(complementHue, 50 + Math.random() * 30, 40 + Math.random() * 20),
hsl: [complementHue, 50 + Math.random() * 30, 40 + Math.random() * 20]
});
colors.push({
hex: hslToHex((baseHue - 30 + 360) % 360, 75 + Math.random() * 15, 60 + Math.random() * 10),
hsl: [(baseHue - 30 + 360) % 360, 75 + Math.random() * 15, 60 + Math.random() * 10]
});
var palette = document.getElementById('palette');
palette.innerHTML = '';
for (var i = 0; i < 5; i++) {
var box = document.createElement('div');
box.className = 'color-box';
box.style.backgroundColor = colors[i].hex;
box.onclick = (function(hex) {
return function() {
if (navigator.clipboard) {
navigator.clipboard.writeText(hex).then(function() {
box.classList.add('copied');
setTimeout(function() {
box.classList.remove('copied');
}, 1000);
});
}
};
})(colors[i].hex);
var hexCode = document.createElement('div');
hexCode.className = 'hex-code';
hexCode.textContent = colors[i].hex;
hexCode.style.color = colors[i].hex === '#FFFFFF' ? '#000' : '#333';
box.appendChild(hexCode);
palette.appendChild(box);
}
}
// Générer la première palette au chargement
window.onload = generatePalette;
</script>
</body>
</html>
xaigrok-4-1-fast-reasoning
9.6/1048.8 s
xaigrok-4-1-fast-reasoning
Tokens1 666
Code source5.0 KB
Temps48.8 s
Jugement Matania
Rendering
9
UX
9
Qualité du code
9
Complétude
10
Fidélité
10
Global
9.63
Revue
Le modèle a parfaitement respecté toutes les contraintes, y compris la zone de 400x400 et l'algorithme de génération de couleurs cohérentes (analogues et complémentaires). L'interface est propre, le feedback visuel de copie est bien implémenté et la gestion de la lisibilité du texte (contraste) est un excellent ajout non demandé.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Générateur de Palette</title>
<style>
body {
margin: 0;
padding: 20px;
background: #f0f0f0;
font-family: sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
#container {
width: 400px;
height: 400px;
background: white;
border-radius: 12px;
box-shadow: 0 8px 20px rgba(0,0,0,0.15);
display: flex;
flex-direction: column;
position: relative;
overflow: hidden;
}
#palette {
flex: 1;
display: flex;
}
.swatch {
flex: 1;
display: flex;
flex-direction: column;
cursor: pointer;
transition: all 0.2s ease;
}
.swatch:hover {
transform: scale(1.005);
}
.color {
flex: 1;
}
.hex {
height: 50px;
display: flex;
align-items: center;
justify-content: center;
font-family: 'Courier New', monospace;
font-size: 16px;
font-weight: bold;
background: rgba(255,255,255,0.92);
border-top: 1px solid #e0e0e0;
}
#regen {
height: 50px;
background: #007bff;
color: white;
border: none;
font-size: 18px;
font-weight: bold;
cursor: pointer;
transition: background 0.2s;
}
#regen:hover {
background: #0056b3;
}
#feedback {
position: absolute;
bottom: 65px;
left: 50%;
transform: translateX(-50%);
background: #28a745;
color: white;
padding: 12px 24px;
border-radius: 25px;
font-weight: bold;
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
white-space: nowrap;
font-size: 14px;
}
</style>
</head>
<body>
<div id="container">
<div id="palette">
<div class="swatch">
<div class="color"></div>
<div class="hex"></div>
</div>
<div class="swatch">
<div class="color"></div>
<div class="hex"></div>
</div>
<div class="swatch">
<div class="color"></div>
<div class="hex"></div>
</div>
<div class="swatch">
<div class="color"></div>
<div class="hex"></div>
</div>
<div class="swatch">
<div class="color"></div>
<div class="hex"></div>
</div>
</div>
<button id="regen">Régénérer</button>
<div id="feedback"></div>
</div>
<script>
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex(r, g, b) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b).toUpperCase();
}
function hslToRgb(h, s, l) {
h /= 360;
var r, g, b;
if (s == 0) {
r = g = b = l;
} else {
function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
function hslToHex(h, s, l) {
var rgb = hslToRgb(h, s, l);
return rgbToHex(rgb[0], rgb[1], rgb[2]);
}
function getTextColor(hex) {
var r = parseInt(hex.substr(1, 2), 16) / 255;
var g = parseInt(hex.substr(3, 2), 16) / 255;
var b = parseInt(hex.substr(5, 2), 16) / 255;
var luminance = 0.299 * r + 0.587 * g + 0.114 * b;
return luminance > 0.5 ? '#000000' : '#FFFFFF';
}
function generatePalette() {
var baseHue = Math.floor(Math.random() * 360);
var compHue = (baseHue + 180) % 360;
var palette = [];
palette.push(hslToHex((baseHue - 30 + 360) % 360, 0.7 + Math.random() * 0.2, 0.5 + Math.random() * 0.2));
palette.push(hslToHex(baseHue, 0.8 + Math.random() * 0.1, 0.45 + Math.random() * 0.25));
palette.push(hslToHex((baseHue + 30) % 360, 0.6 + Math.random() * 0.3, 0.55 + Math.random() * 0.15));
palette.push(hslToHex(compHue, 0.75 + Math.random() * 0.15, 0.5 + Math.random() * 0.2));
palette.push(hslToHex((compHue + 20) % 360, 0.65 + Math.random() * 0.2, 0.4 + Math.random() * 0.3));
return palette;
}
function setPalette(colors) {
var swatches = document.querySelectorAll('.swatch');
for (var i = 0; i < swatches.length; i++) {
var swatch = swatches[i];
swatch.querySelector('.color').style.backgroundColor = colors[i];
var hexEl = swatch.querySelector('.hex');
hexEl.textContent = colors[i];
hexEl.style.color = getTextColor(colors[i]);
}
}
var swatches = document.querySelectorAll('.swatch');
var feedback = document.getElementById('feedback');
var regen = document.getElementById('regen');
function showFeedback(msg) {
feedback.textContent = msg;
feedback.style.opacity = '1';
setTimeout(function() {
feedback.style.opacity = '0';
}, 2000);
}
for (var i = 0; i < swatches.length; i++) {
swatches[i].addEventListener('click', function() {
var hex = this.querySelector('.hex').textContent;
navigator.clipboard.writeText(hex).then(function() {
showFeedback('Copié !');
}).catch(function() {
showFeedback('Erreur de copie');
});
});
}
regen.addEventListener('click', function() {
var colors = generatePalette();
setPalette(colors);
});
setPalette(generatePalette());
</script>
</body>
</html>