.qcmf-btn { color: #111 !important; /* Texte noir forcé */ font-weight: 500; } .qcmf-wrap { font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; max-width: 800px; margin: 24px auto; padding: 16px; } .qcmf-card { background: #fff; border-radius: 16px; box-shadow: 0 10px 30px rgba(0,0,0,.08); padding: 24px; } .qcmf-header { display:flex; justify-content:space-between; align-items:center; margin-bottom: 12px; gap:12px; flex-wrap: wrap; } .qcmf-title { font-size: clamp(18px, 2.4vw, 22px); font-weight: 700; margin:0; } .qcmf-badge { font-size:12px; padding:6px 10px; border-radius:999px; background:#f2f4f7; } .qcmf-progress { height:10px; background:#eef2f7; border-radius:999px; overflow:hidden; margin:12px 0 20px; } .qcmf-progress > div { height:100%; width:0; background: linear-gradient(90deg,#4f46e5,#22c55e); transition: width .35s ease; } .qcmf-question { font-size: clamp(18px, 2.6vw, 22px); line-height: 1.4; margin: 10px 0 14px; } .qcmf-ctx { color:#475569; font-size:14px; margin-top:-6px; margin-bottom:10px; } .qcmf-options { display:grid; gap:12px; grid-template-columns: 1fr; } .qcmf-btn { border:1px solid #e5e7eb; background:#fff; border-radius: 12px; padding: 12px 14px; text-align:left; cursor:pointer; font-size:16px; transition: transform .06s ease, border-color .2s, background .2s; } .qcmf-btn:hover { transform: translateY(-1px); border-color:#c7d2fe; background:#f8fafc; } .qcmf-btn[disabled] { opacity:.8; cursor:not-allowed; } .qcmf-btn.correct { border-color:#22c55e; background:#ecfdf5; } .qcmf-btn.wrong { border-color:#ef4444; background:#fef2f2; } .qcmf-feedback { margin-top: 12px; padding: 12px 14px; border-left: 4px solid #e5e7eb; border-radius:10px; background:#f8fafc; font-size:14px; } .qcmf-feedback.good { border-color:#22c55e; background:#ecfdf5; } .qcmf-feedback.bad { border-color:#ef4444; background:#fef2f2; } .qcmf-actions { display:flex; gap:10px; margin-top:16px; flex-wrap: wrap; } .qcmf-cta { border:none; border-radius:10px; padding:10px 14px; font-weight:600; cursor:pointer; } .qcmf-cta.primary { background:#4f46e5; color:#fff; } .qcmf-cta.secondary { background:#e5e7eb; } .qcmf-footer { margin-top:24px; display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap: wrap; } .qcmf-meter { font-size:14px; color:#334155; background:#f1f5f9; padding:6px 10px; border-radius:8px; } .qcmf-encourage { font-size:14px; color:#1f2937; } .qcmf-note { font-size: clamp(20px, 3vw, 28px); font-weight:800; } @media (min-width: 640px) { .qcmf-options { grid-template-columns: 1fr 1fr; } } (function(){ // ——– 1) JSON des questions (facile -> difficile) ——– // Chaque item: { id, contexte, question, options[4], correctIndex, explications[4], tagDifficulte } const QUESTIONS = [ { id: 1, tagDifficulte: « Facile », contexte: « Présent de l’indicatif », question: « Je (manger) une pomme. », options: [« manges », « mange », « mangent », « mangé »], correctIndex: 1, explications: [ « “manges” va avec “tu”, pas avec “je”. », « Correct : “je mange”. », « “mangent” va avec “ils/elles”. », « “mangé” est un participe passé, pas une forme conjuguée ici. » ] }, { id: 2, tagDifficulte: « Facile », contexte: « Présent de l’indicatif », question: « Tu (aller) au collège. », options: [« va », « vas », « allez », « irai »], correctIndex: 1, explications: [ « “va” correspond à “il/elle/on va”. », « Correct : “tu vas”. », « “allez” correspond à “vous”. », « “irai” est au futur simple, pas au présent. » ] }, { id: 3, tagDifficulte: « Facile », contexte: « Présent de l’indicatif (2e groupe) », question: « Il (finir) son exercice. », options: [« finis », « finissent », « finit », « fini »], correctIndex: 2, explications: [ « “finis” va avec “je/tu”. », « “finissent” va avec “ils/elles”. », « Correct : “il finit”. », « “fini” est un participe passé. » ] }, { id: 4, tagDifficulte: « Facile », contexte: « Présent de l’indicatif (verbe irrégulier) », question: « Nous (avoir) faim. », options: [« avons », « avez », « ont », « aurons »], correctIndex: 0, explications: [ « Correct : “nous avons”. », « “avez” correspond à “vous”. », « “ont” correspond à “ils/elles”. », « “aurons” est au futur simple. » ] }, { id: 5, tagDifficulte: « Facile », contexte: « Présent de l’indicatif (verbe du 1er groupe) », question: « Vous (commencer) maintenant. », options: [« commençons », « commencez », « commencent », « commencer »], correctIndex: 1, explications: [ « “commençons” correspond à “nous” (avec cédille). », « Correct : “vous commencez”. », « “commencent” correspond à “ils/elles”. », « Infinitif : pas conjugué. » ] }, { id: 6, tagDifficulte: « Moyen », contexte: « Passé composé (auxiliaire avoir) », question: « Hier, ils (prendre) le bus. », options: [« ont pris », « sont pris », « ont prendu », « prirent »], correctIndex: 0, explications: [ « Correct : “ils ont pris”. », « “prendre” se conjugue avec “avoir”, pas “être”. », « Le participe passé est “pris”, pas “prendu”. », « “prirent” est au passé simple, pas au passé composé. » ] }, { id: 7, tagDifficulte: « Moyen », contexte: « Imparfait », question: « Quand nous étions petit·e·s, nous (faire) du vélo. », options: [« faisaient », « faisions », « faisons », « ferions »], correctIndex: 1, explications: [ « “faisaient” va avec “ils/elles”. », « Correct : “nous faisions” (imparfait). », « “faisons” est un présent. », « “ferions” est un conditionnel. » ] }, { id: 8, tagDifficulte: « Moyen », contexte: « Futur simple », question: « Demain, elle (venir) plus tôt. », options: [« viendra », « vient », « venait », « viendrait »], correctIndex: 0, explications: [ « Correct : “elle viendra”. », « “vient” est au présent. », « “venait” est à l’imparfait. », « “viendrait” est au conditionnel. » ] }, { id: 9, tagDifficulte: « Moyen+ », contexte: « Passé composé (auxiliaire être, accord) », question: « Elles (aller) au cinéma. », options: [« ont allé », « sont allées », « étaient allées », « sont allé »], correctIndex: 1, explications: [ « Avec “aller”, l’auxiliaire est “être”, pas “avoir”. », « Correct : “elles sont allées” (+ accord féminin pluriel). », « “étaient allées” = plus-que-parfait, pas passé composé. », « Avec “être”, on accorde : il faut “allées”. » ] }, { id: 10, tagDifficulte: « Moyen+ », contexte: « Conditionnel présent », question: « Je (aimer) voyager plus. », options: [« aime », « aimerai », « aimerais », « aimais »], correctIndex: 2, explications: [ « “aime” = présent ; ici on exprime un souhait/une hypothèse. », « “aimerai” = futur simple (sans ‘s’). », « Correct : “j’aimerais” (conditionnel). », « “aimais” = imparfait. » ] }, { id: 11, tagDifficulte: « Difficile », contexte: « Subjonctif présent », question: « Il faut que tu (venir) à l’heure. », options: [« viens », « viendras », « viennes », « venais »], correctIndex: 2, explications: [ « “viens” = présent de l’indicatif. », « “viendras” = futur simple. », « Correct : subjonctif présent “que tu viennes”. », « “venais” = imparfait. » ] }, { id: 12, tagDifficulte: « Difficile », contexte: « Plus-que-parfait (auxiliaire avoir) », question: « Il (déjà finir) quand je suis arrivé·e. », options: [« avait déjà fini », « a déjà fini », « avait déjà finissait », « finit déjà »], correctIndex: 0, explications: [ « Correct : “il avait déjà fini” (plus-que-parfait). », « Ici on situe une action antérieure à un passé : on n’utilise pas le passé composé. », « “finissait” ne va pas après “avait déjà”. », « “finit” est un présent/ passé simple hors contexte. » ] }, { id: 13, tagDifficulte: « Difficile », contexte: « Accord du participe passé (COD placé avant) », question: « Les lettres qu’il a (écrire) hier. », options: [« écrits », « écrites », « écrit », « écritent »], correctIndex: 1, explications: [ « Masculin pluriel ; mais “lettres” est féminin pluriel. », « Correct : COD “les lettres” est placé avant → “écrites”. », « Pas d’accord si COD après ; ici il est avant. », « “écritent” n’existe pas. » ] }, { id: 14, tagDifficulte: « Très difficile », contexte: « Subjonctif présent (verbe être) », question: « Je doute qu’ils (être) prêts. », options: [« sont », « seront », « soient », « étaient »], correctIndex: 2, explications: [ « Indicatif présent ; après “je doute que”, on met le subjonctif. », « Futur simple ; pas adapté au doute. », « Correct : “qu’ils soient”. », « Imparfait ; pas le bon mode ici. » ] }, { id: 15, tagDifficulte: « Très difficile », contexte: « Futur antérieur vs futur simple », question: « Quand tu (arriver), nous partirons. », options: [« seras arrivé·e », « arrives », « es arrivé·e », « arriveras »], correctIndex: 0, explications: [ « Correct : action accomplie avant une autre future → futur antérieur. », « Présent ; pas la bonne relation temporelle. », « Passé composé ; on parle d’un fait futur. », « Futur simple ; ne marque pas l’antériorité. » ] } ]; // ——– 2) UI / Logique ——– const elRoot = document.getElementById(« qcm-francais-conjugaison »); if (!elRoot) return; // Utilitaire: créer un élément const h = (tag, attrs={}, …children) => { const el = document.createElement(tag); for (const [k,v] of Object.entries(attrs||{})) { if (k === « class ») el.className = v; else if (k === « html ») el.innerHTML = v; else el.setAttribute(k, v); } for (const c of children) { if (c == null) continue; if (typeof c === « string ») el.appendChild(document.createTextNode(c)); else el.appendChild(c); } return el; }; // État let index = 0; // question courante let correct = 0; // nb bonnes réponses let answered = false; // verrouillage double clic // Encouragements dynamiques const feedbackShort = (ratio) => { if (ratio === 1) return « 🔥 Parfait ! Tu gères. »; if (ratio >= 0.8) return « 💪 Super rythme, continue ! »; if (ratio >= 0.6) return « 👍 C’est bien parti, persévère. »; if (ratio >= 0.4) return « ✨ Tu progresses, ne lâche pas. »; return « 🌱 Chaque essai te fait avancer. Courage ! »; }; function render() { elRoot.innerHTML = «  »; const total = QUESTIONS.length; const q = QUESTIONS[index]; // En-tête + progression const header = h(« div », {class: »qcmf-header »}, h(« h2″,{class: »qcmf-title »}, »Exercice de français — Conjugue le verbe »), h(« span »,{class: »qcmf-badge »}, `Question ${index+1} / ${total}`) ); const progress = h(« div »,{class: »qcmf-progress »}, h(« div »,{style:`width:${((index)/total)*100}%`})); // Carte question const card = h(« div »,{class: »qcmf-card »}, header, progress, h(« div »,{class: »qcmf-ctx »}, `${q.contexte} • Difficulté : ${q.tagDifficulte}`), h(« div »,{class: »qcmf-question »}, q.question), renderOptions(q), h(« div »,{class: »qcmf-footer »}, h(« div »,{class: »qcmf-meter »}, `Bonnes réponses : ${correct}/${index} • ${index ? Math.round((correct/index)*100) : 0}%`), h(« div »,{class: »qcmf-encourage »}, feedbackShort(index ? correct/index : 0)) ) ); elRoot.appendChild(card); } function renderOptions(q) { const wrap = h(« div »,{class: »qcmf-options »}); answered = false; q.options.forEach((opt, i) => { const btn = h(« button »,{class: »qcmf-btn », type: »button »}, opt); btn.addEventListener(« click », () => { if (answered) return; answered = true; const ok = i === q.correctIndex; if (ok) { correct++; btn.classList.add(« correct »); } else { btn.classList.add(« wrong »); } // Désactiver tous les boutons, marquer la bonne […wrap.children].forEach((b, idx) => { b.setAttribute(« disabled », « true »); if (idx === q.correctIndex) b.classList.add(« correct »); }); const fb = h(« div »,{class:`qcmf-feedback ${ok?’good’:’bad’}`}, ok ? « Bien joué ! ✅ » : `Oups… ❌ ${q.explications[i]}` ); const actions = h(« div »,{class: »qcmf-actions »}); const next = h(« button »,{class: »qcmf-cta primary », type: »button »}, (index { if (index { // Remettre l’explication en avant (petite animation visuelle légère) fb.style.transition = « transform .15s ease »; fb.style.transform = « scale(1.02) »; setTimeout(()=> fb.style.transform= »scale(1) », 120); }); wrap.appendChild(fb); actions.appendChild(next); actions.appendChild(retry); wrap.appendChild(actions); }); wrap.appendChild(btn); }); return wrap; } function renderResult() { elRoot.innerHTML = «  »; const total = QUESTIONS.length; const ratio = correct / total; const note20 = Math.round((correct / total) * 20 * 10) / 10; // arrondi au dixième const card = h(« div »,{class: »qcmf-card »}, h(« div »,{class: »qcmf-header »}, h(« h2″,{class: »qcmf-title »}, »Résultat — Conjugue le verbe »), h(« span »,{class: »qcmf-badge »}, `${correct}/${total} bonnes réponses`) ), h(« div »,{class: »qcmf-progress »}, h(« div »,{style:`width:${ratio*100}%`})), h(« p »,{}, `Taux de réussite : ${Math.round(ratio*100)}%`), h(« p »,{class: »qcmf-note »}, `Note : ${note20} / 20`), h(« div »,{class:`qcmf-feedback ${ratio>=0.6?’good’:’bad’}`}, ratio>=0.8 ? « Excellent niveau ! Tu maîtrises vraiment les conjugaisons. 🔥 » : ratio>=0.6 ? « Beau travail ! Encore un petit effort pour atteindre le top. 💪 » : ratio>=0.4 ? « Tu progresses. Revois surtout les temps simples (présent, imparfait) et les accords. ✨ » : « Courage, c’est en s’entraînant qu’on devient fort·e ! Reprends les bases et réessaie. 🌱 » ), h(« div »,{class: »qcmf-actions »}, (function(){ const again = h(« button »,{class: »qcmf-cta primary », type: »button »}, »Recommencer l’exercice »); again.addEventListener(« click », () => { index = 0; correct = 0; render(); }); return again; })(), (function(){ const review = h(« button »,{class: »qcmf-cta secondary », type: »button »}, »Revoir toutes les questions »); review.addEventListener(« click », () => { index = 0; render(); }); return review; })() ) ); elRoot.appendChild(card); } // Démarrer render(); })();