0 / 50 leçons
0%
playground.html ✎ Modifiable
RÉSULTAT EN DIRECT
`, keyPoints: [ { title: "Checklist avant publication", desc: "DOCTYPE, lang, charset, viewport, title, alt sur images" }, { title: "Valider son HTML", desc: "validator.w3.org valide votre HTML contre les standards W3C" }, { title: "Prochaine étape : CSS", desc: "Flexbox, Grid, animations — donnez vie à votre HTML" }, { title: "SEO de base", desc: "title, meta description, h1 unique, balises sémantiques = bon départ" } ], starter: `

Aminata.dev

👋 À propos de moi

Je suis Aminata Diallo, développeuse web junior basée à Dakar, Sénégal. Je crée des interfaces web belles et accessibles pour aider les entreprises africaines à grandir en ligne.

✉️ aminata@exemple.sn

🚀 Mes Projets

Capture du projet boutique en ligne

Boutique en Ligne — MarketSN

Site e-commerce avec catalogue produits, panier et formulaire de commande.

HTML CSS JavaScript

Blog Tech Sénégal

Blog sur le développement web et les opportunités tech en Afrique de l'Ouest.

Technologies : HTML • CSS

🎯 Compétences

Compétences techniques
🌐 HTML590%
🎨 CSS370%
⚡ JavaScript40%

✉️ Me Contacter

* Champs obligatoires — Réponse sous 48h

` } ] /* ════════════════════════════════════════════ CATÉGORIES ═══════════════════════════════════════════════ */ const CATEGORIES = [ { label: "Texte & Structure", range: [0, 5] }, { label: "Données & Médias", range: [6, 11] }, { label: "Mise en page", range: [12, 17] }, { label: "Formatage", range: [18, 22] }, { label: "Sémantique", range: [23, 29] }, { label: "Formulaires", range: [30, 34] }, { label: "Inputs avancés", range: [35, 39] }, { label: "Inputs spéciaux", range: [40, 41] }, { label: "Projet Final", range: [42, 42] } ] /* ════════════════════════════════════════════ ÉTAT ═══════════════════════════════════════════════ */ let currentLesson = 0 let doneLessons = new Set() try { doneLessons = new Set(JSON.parse(localStorage.getItem("doneLessons_html2") || "[]")) } catch(e) {} /* ════════════════════════════════════════════ SIDEBAR ═══════════════════════════════════════════════ */ function buildSidebar() { const sb = document.getElementById("sidebar") sb.innerHTML = "" CATEGORIES.forEach(cat => { const sec = document.createElement("div") sec.className = "sidebar-section" sec.textContent = cat.label sb.appendChild(sec) for (let i = cat.range[0]; i <= cat.range[1] && i < lessons.length; i++) { const item = document.createElement("div") item.className = "sidebar-item" + (i === currentLesson ? " active" : "") + (doneLessons.has(i) ? " done" : "") item.dataset.idx = i const title = lessons[i].title.replace(/🎓 /,"") item.innerHTML = `${String(i+1).padStart(2,"0")}${title}` item.addEventListener("click", () => goTo(i)) sb.appendChild(item) } }) } /* ════════════════════════════════════════════ HIGHLIGHT ═══════════════════════════════════════════════ */ function escapeHtml(s) { return s.replace(/&/g,"&").replace(//g,">").replace(/"/g,""") } function highlightHtml(code) { let e = escapeHtml(code) e = e.replace(/<!--[\s\S]*?-->/g, m => `${m}`) e = e.replace(/(<\/?)([\w-]+)/g, (m,sl,tag) => `${sl}${tag}`) e = e.replace(/([\w-]+)(=)("[^&]*")/g, (m,a,eq,v) => `${a}${eq}${v}`) e = e.replace(/\s(required|checked|disabled|multiple|open|controls|autoplay|loop|muted|selected|defer|async)(?=[>\s\/])/g, m => ` ${m.trim()}`) return e } /* ════════════════════════════════════════════ RENDU LEÇON ═══════════════════════════════════════════════ */ function renderLesson() { const l = lessons[currentLesson] const inner = document.getElementById("lesson-inner") const diffLabel = { debutant: "Débutant", intermediaire: "Intermédiaire", avance: "Avancé" }[l.difficulty] const diffClass = { debutant: "diff-debutant", intermediaire: "diff-intermediaire", avance: "diff-avance" }[l.difficulty] // Objectifs const objHTML = l.objectives ? `
🎯 Ce que vous allez apprendre
` : "" // Syntax table const synHTML = l.syntaxItems ? `
📖 Référence syntaxique
${l.syntaxItems.map(s => ``).join("")}
${escapeHtml(s.tag)}${s.desc}
` : "" // Key points const kpHTML = l.keyPoints ? `
💡 Points clés à retenir
${l.keyPoints.map(k => `
${k.title}${k.desc}
`).join("")}
` : "" // Boutons nav const nextLesson = currentLesson < lessons.length - 1 ? lessons[currentLesson + 1].title.replace(/🎓 /,"") : "" const navHTML = ` ` inner.innerHTML = `
Leçon ${String(currentLesson+1).padStart(2,"0")} / ${lessons.length} ${l.category} ${diffLabel}

${l.title}

${l.subtitle ? `

${l.subtitle}

` : ""} ${objHTML}
${l.desc}
${synHTML}
exemple.html
${highlightHtml(l.code)}
${kpHTML} ${navHTML} ` document.getElementById("lesson-panel").scrollTop = 0 document.getElementById("editor").value = l.starter runCode() updateProgress() } /* ════════════════════════════════════════════ NAVIGATION ═══════════════════════════════════════════════ */ function goTo(idx) { currentLesson = idx buildSidebar() renderLesson() } function markAndNext() { doneLessons.add(currentLesson) try { localStorage.setItem("doneLessons_html2", JSON.stringify([...doneLessons])) } catch(e) {} goTo(currentLesson + 1) } function markDone() { doneLessons.add(currentLesson) try { localStorage.setItem("doneLessons_html2", JSON.stringify([...doneLessons])) } catch(e) {} buildSidebar() updateProgress() const btn = document.querySelector(".nav-btn.next") if (btn) btn.textContent = "🎓 Cours terminé !" } function loadExample() { document.getElementById("editor").value = lessons[currentLesson].code runCode() } function updateProgress() { const pct = Math.round(doneLessons.size / lessons.length * 100) document.getElementById("progress-fill").style.width = pct + "%" document.getElementById("progress-text").textContent = `${doneLessons.size} / ${lessons.length} leçons` document.getElementById("progress-pct").textContent = pct + "%" } /* ════════════════════════════════════════════ PLAYGROUND ═══════════════════════════════════════════════ */ function runCode() { const code = document.getElementById("editor").value const iframe = document.getElementById("result").contentWindow.document iframe.open() iframe.write(`${code}`) iframe.close() } /* ════════════════════════════════════════════ INIT ═══════════════════════════════════════════════ */ buildSidebar() renderLesson()