diff --git a/B-les-bases.md b/B-les-bases.md
index 6759faeefce87389a67e2f9df1ae5b545a22bda2..2375f0049799e49e111b031b412410d17bb0470c 100644
--- a/B-les-bases.md
+++ b/B-les-bases.md
@@ -1,93 +1,84 @@
-#### TP3 - API DOM <!-- omit in toc -->
-# B. Les bases de l'API DOM <!-- omit in toc -->
-
-## Sommaire <!-- omit in toc -->
-- [B.1. Configuration du projet](#b1-configuration-du-projet)
-- [B.2. Sélectionner des éléments](#b2-sélectionner-des-éléments)
-	- [B.2.1. querySelector()](#b21-queryselector)
-	- [B.2.2. querySelectorAll()](#b22-queryselectorall)
-- [B.3. Modifier des éléments](#b3-modifier-des-éléments)
-	- [B.3.1. innerHTML](#b31-innerhtml)
-	- [B.3.2. getAttribute/setAttribute](#b32-getattributesetattribute)
-- [Étape suivante](#étape-suivante)
+<img src="images/readme/header-small.jpg" >
 
-***Ce TP va permettre de mettre en oeuvre les principales méthodes de sélection et de modification d'éléments de l'arbre DOM.***
+# B. Les bases de l'API DOM <!-- omit in toc -->
 
-## B.1. Configuration du projet
+_**Dans cette partie du TP, nous allons prendre en main les méthodes de base de l'API DOM et notamment celles de sélection et de modification d'éléments de l'arbre DOM.**_
 
-**Ce repo contient une solution commentée du précédent TP. Il servira de base au T3 :**
+## Sommaire <!-- omit in toc -->
+- [B.1. Sélectionner des éléments](#b1-sélectionner-des-éléments)
+	- [B.1.1. querySelector()](#b11-queryselector)
+	- [B.1.2. querySelectorAll()](#b12-queryselectorall)
+- [B.2. Modifier des éléments](#b2-modifier-des-éléments)
+	- [B.2.1. innerHTML](#b21-innerhtml)
+	- [B.2.2. getAttribute/setAttribute](#b22-getattributesetattribute)
 
-1. Clonez le projet
-	```bash
-	mkdir -p ~/ws-js/tp3
-	git clone https://gitlab.univ-lille.fr/js/tp3.git ~/ws-js/tp3
-	```
-2. Lancez VSCodium :
-	```bash
-	codium ~/ws-js/tp3
-	```
-3. Ouvrez un terminal intégré dans VSCodium à l'aide du raccourci <kbd>CTRL</kbd>+<kbd>J</kbd> et installez les dépendances du projet :
-	```bash
-	npm install
-	```
-4. **Une fois tout installé, vous pouvez relancer la compilation à l'aide de la commande `npm run watch` et lancer le serveur http avec `npx serve -l 8000`**. Vérifiez ensuite que la page s'affiche correctement dans le navigateur :<br><a href="images/readme/pizzaland-05.png"><img src="images/readme/pizzaland-05.png" width="80%"></a>
 
-## B.2. Sélectionner des éléments
+## B.1. Sélectionner des éléments
 
-### B.2.1. querySelector()
-Comme vu en cours, la principale méthode pour sélectionner un élément de la page HTML est la méthode `querySelector()`.
+### B.1.1. querySelector()
+**Comme vu en cours, la principale méthode pour sélectionner un élément de la page HTML est la méthode [`querySelector()`](https://developer.mozilla.org/fr/docs/Web/API/Document/querySelector).**
 
-querySelector() est une méthode de la classe `Element` qui permet de retourner une référence vers un élément de la page (une balise) à partir d'un sélecteur CSS. Par exemple :
+`querySelector()` est une méthode de la classe `Element` qui retourne une référence vers le premier élément de la page (_une balise_) qui correspond au sélecteur CSS passé en paramètre. Par exemple :
 ```js
-document.querySelector('#appContainer');
+document.querySelector('.pageContainer');
 ```
-retourne la balise d'id html 'appContainer' :
+retourne (_si elle existe !_) la balise ayant comme classe CSS `'pageContainer'` :
 ```html
-<main id="appContainer">
+<section class="pageContainer">
 ```
 
-Dans le fichier `main.js`, utilisez la fonction `console.log()` et la méthode `querySelector` pour afficher la balise qui a comme classe `"pageTitle"` comme ceci :
+**Ouvrez les devtools de votre navigateur, et dans la console, tapez le code suivant :**
 ```js
-console.log( document.querySelector('.pageTitle') );
+document.querySelector('.pizzaList')
 ```
+cette instruction vous retourne la balise qui a comme classe `"pizzaList"`
+
+<img src="images/readme/queryselector-pizzaList.png" >
 
-Sur le même modèle, affichez dans la console  :
+**Sur le même principe, affichez dans la console :**
 1. La balise `<img>` qui contient le logo de la page (les 2 parts de pizza)
 2. Le lien du menu "Ajouter une pizza"
-3. Le lien vers le site [Unsplash](https://unsplash.com/) dans les crédits
-4. le titre de la première pizza (*`<h4>Regina</h4>`*)
+3. le titre de la première pizza (`Regina`)
 
-<a href="images/readme/queryselector-console.jpg"><img src="images/readme/queryselector-console.jpg" width="80%"></a>
+<img src="images/readme/queryselector-console.png">
 
-### B.2.2. querySelectorAll()
-La méthode `querySelectorAll()` permet de récupérer non pas un, mais tous les éléments qui correspondent au sélecteur CSS passé en paramètre.
+### B.1.2. querySelectorAll()
+**La méthode [`querySelectorAll()`](https://developer.mozilla.org/fr/docs/Web/API/Document/querySelectorAll) permet de récupérer non pas un, mais tous les éléments qui correspondent au sélecteur CSS passé en paramètre.**
 
 Affichez dans la console :
-1. la liste des liens du menu de navigation ("La carte" et "Ajouter une pizza")
-2. la liste des prix de toutes les pizzas de la page
+1. **la liste des liens du menu de navigation** ("La carte", "À propos" et "Ajouter une pizza")
+2. **la liste des `<li>` contenant le prix de toutes les pizzas**
 
-<a href="images/readme/queryselectorall-console.jpg"><img src="images/readme/queryselectorall-console.jpg" width="80%"></a>
+<img src="images/readme/queryselectorall-console.png">
 
-## B.3. Modifier des éléments
-### B.3.1. innerHTML
-La propriété `innerHTML` permet à la fois de lire et de modifier le contenu d'un Element HTML (le contenu HTML compris entre les balises ouvrantes et fermantes)
+## B.2. Modifier des éléments
+### B.2.1. innerHTML
+**La propriété [`innerHTML`](https://developer.mozilla.org/fr/docs/Web/API/Element/innertHTML) permet à la fois de lire et de modifier le contenu d'un Element HTML** (_tout ce qui est compris **entre** les balises ouvrantes et fermantes_)
 
-1. Affichez dans la console le titre de la deuxième pizza (*"Napolitaine"*)
-2. Remplacez dans la page le titre de la deuxième pizza par *"Savoyarde"*
-3. Ajoutez au titre de la page le code HTML suivant :
+1. Affichez dans la console le **titre de la deuxième pizza** (_la chaîne de caractères_ `"Napolitaine"`)
+2. **Ajoutez au logo** (_grâce à la propriété `innerHTML`_) le code HTML suivant :
 	```html
-	<small class="label label-success">les pizzas c'est la vie</small>
+	<small>les pizzas c'est la vie</small>
 	```
+	De manière à obtenir :
+	```html
+	<a href="#" class="logo">
+		<img src="images/logo.svg" />
+		<span>Pizza<em>land</em></span>
+		<small>les pizzas c'est la vie</small>
+	</a>
+	```
+
+	<img src="images/readme/pizzaland-innerhtml.png">
 
-<a href="images/readme/pizzaland-innerhtml.png"><img src="images/readme/pizzaland-innerhtml.png" width="80%"></a>
+### B.2.2. getAttribute/setAttribute
+**Les méthodes [`getAttribute()`](https://developer.mozilla.org/fr/docs/Web/API/Element/getAttribute) et [`setAttribute()`](https://developer.mozilla.org/fr/docs/Web/API/Element/setAttribute) de la classe `Element` permettent de lire, d'ajouter ou de modifier des attributs HTML.**
 
-### B.3.2. getAttribute/setAttribute
-Les méthodes `getAttribute()` et `setAttribute()` de la classe Element permettent de lire, d'ajouter ou de modifier des attributs HTML.
+1. Affichez dans la console **l'url du 2e lien contenu dans le footer** (`"https://www.iut-a.univ-lille.fr/"`)
+2. **Ajoutez la classe CSS `"active"`** au premier lien du menu ("La carte")
 
-1. Affichez dans la console l'url du 2e lien contenu dans le footer (`"https://www.freepik.com/"`)
-2. Ajoutez la classe CSS "active" au premier `<li>` du menu
+	<img src="images/readme/pizzaland-setattribute.png">
 
-<a href="images/readme/pizzaland-setattribute.png"><img src="images/readme/pizzaland-setattribute.png" width="80%"></a>
 
-## Étape suivante
+## Étape suivante <!-- omit in toc -->
 Maintenant que l'on est capable de sélectionner / modifier des éléments HTML, nous allons voir dans le prochain exercice comment détecter les événements : [C. Les événements](./C-evenements.md).
\ No newline at end of file
diff --git a/C-evenements.md b/C-evenements.md
index 555a4336fc5b1422a68b3f8dfc7d7e89203765af..5df35a11317cc99671ff222376f2b9f69cb8e6d3 100644
--- a/C-evenements.md
+++ b/C-evenements.md
@@ -1,57 +1,135 @@
-#### TP3 - API DOM <!-- omit in toc -->
+<img src="images/readme/header-small.jpg" >
+
 # C. Les événements de l'API DOM <!-- omit in toc -->
 
+_**Maintenant que l'on sait sélectionner et modifier des éléments de la page HTML, voyons comment réagir aux actions de l'utilisateurs avec les événements et notamment comment mettre en place un système de navigation dans notre application.**_
+
 ## Sommaire <!-- omit in toc -->
 - [C.1. Rappels](#c1-rappels)
-- [C.2. La gestion du menu](#c2-la-gestion-du-menu)
-- [C.3. Navigation en JS](#c3-navigation-en-js)
-- [Étape suivante](#étape-suivante)
+- [C.2. Navigation en JS : afficher/masquer un élément](#c2-navigation-en-js-affichermasquer-un-élément)
+- [C.2. Navigation en JS : Le menu](#c2-navigation-en-js-le-menu)
 
 
 ## C.1. Rappels
-**Le système d'événements en JS permet de réagir à des actions de l'utilisateur (survol d'un élément, click sur un lien, soumission d'un formulaire, etc.) ou à des événements déclenchés par le navigateur (fin du chargement de la page ou d'une image, etc.).**
+**Le système d'événements en JS permet de réagir à des actions de l'utilisateur (_survol d'un élément, click sur un lien, soumission d'un formulaire, etc._) ou à des événements déclenchés par le navigateur (_fin du chargement de la page ou d'une image, etc._).**
 
-Comme vu en cours (cf. pdf du cours sur moodle) on peut associer une fonction à un événement grâce à la méthode `addEventListener()` de la classe Element.
+Comme vu en cours (cf. pdf du cours sur moodle) on peut **associer une fonction à un événement grâce à la méthode [`addEventListener()`](https://developer.mozilla.org/fr/docs/Web/API/EventTarget/addEventListener)** de la classe `Element`.
 
-Par exemple, pour déclencher la fonction `handleClick` lors du clic sur le premier lien de la page, on peut écrire :
-```JavaScript
+Par exemple, pour déclencher une fonction nommée `handleClick` lors du clic sur le premier lien de la page, on peut écrire :
+```js
 function handleClick( event ) {
-	event.preventDefault();
+	event.preventDefault(); // empêche le rechargement de la page
 	console.log(event);
 }
-const link = document.querySelector('a');
-link.addEventListener('click', handleClick);
+const link = document.querySelector('a'); // sélectionne le premier lien de la page
+link.addEventListener('click', handleClick); // écoute l'événement
 ```
 
-Notez que comme vu en cours :
-1. le 2e paramètre que l'on passe à addEventListener est une référence vers la fonction `handleClick` et pas l'exécution de la fonction (`handleClick()`)
-2. la fonction qui est passée à `addEventListener()` recevra un objet de la classe [`Event`](https://developer.mozilla.org/en-US/docs/Web/API/Event)
-3. Il faut presque systématiquement (sauf cas  particuliers) appeler en premier lieu la méthode `event.preventDefault()` : cette méthode permet d'éviter que le navigateur n'exécute le traitement par défaut de l'événement (par exemple rediriger l'utilisateur vers une nouvelle page lorsqu'il clique sur un lien, recharger la page lorsqu'il soumet un formulaire, etc.).
+**Notez que comme vu en cours :**
+1. le 2e paramètre que l'on passe à addEventListener est une **référence de la fonction `handleClick`** (_son nom_) et pas l'exécution de la fonction (`handleClick()` _avec les parenthèses_)
+2. la fonction qui est passée à `addEventListener()` **reçoit automatiquement en paramètre un objet de type [`Event`](https://developer.mozilla.org/en-US/docs/Web/API/Event)**
+3. Il faut presque systématiquement (_sauf cas très particuliers_) **appeler en premier lieu la méthode `event.preventDefault()`** : cette méthode permet d'éviter que le navigateur n'exécute le traitement par défaut de l'événement (par exemple rediriger l'utilisateur vers une nouvelle page lorsqu'il clique sur un lien, recharger la page lorsqu'il soumet un formulaire, etc.).
+4. **Si vous êtes dans une classe, prenez garde aux problèmes de scope** liés à `addEventListener()` (_`this` est toujours l'élément HTML qui a déclenché l'événement_) et préférez l'emploi de arrow functions en inline comme ceci :
+	```js
+	myElement.addEventListener('click', event => {
+		// ici pas de problème de scope, `this` est préservé
+		event.preventDefault();
+		this.monAutreMethode(); // ok
+	});
+	```
+
+## C.2. Navigation en JS : afficher/masquer un élément
+**Il existe plusieurs façons de gérer la navigation en JS.**
+
+**On peut soit générer du code HTML entièrement en JS et l'injecter dans la page (_comme on le fait déjà pour la `PizzaList`_) soit se contenter d'afficher/masquer des portions de la page déjà présentes dans le code html.** \
+**C'est cette technique que l'on va maintenant travailler.**
 
-## C.2. La gestion du menu
-Dans le fichier `main.js` :
-1. **Commencez par commenter le code de l'exercice [B. Les bases de l'API DOM](./B-les-bases.md)** (certains sélecteurs pourront vous être utiles par la suite)
-2. A l'aide de `querySelector()` et `addEventListener()`, **affichez un message dans la console à chaque fois que l'utilisateur clique sur le lien du menu de navigation "Ajouter une pizza"**
-3. **Effacez le code précédent et remplacez le par un code qui permette d'écouter le clic sur *tous* les liens du menu de navigation** :
+1. **Inspectez le code du fichier `index.html`** : vous remarquerez qu'après la balise `<header>` se trouve une balise masquée (_avec `display:none`_) :
+	```html
+	<section class="newsContainer" style="display:none">...</section>
+	```
+2. **Dans `src/main.js` rendez cette section visible** à l'écran à l'aide de la méthode `setAttribute()`.
 
-	Au clic sur n'importe quel lien de la navigation (actuellement il n'y a dans le menu que les liens "La carte" et "Ajouter une pizza", mais ce code doit fonctionner quelque soit le nombre de liens dans le menu) afficher dans la console le libellé du lien qui a été cliqué grâce à `event.currentTarget` (type `EventTarget`) et `element.innerHTML` : par exemple si l'utilisateur clique sur le lien "La carte" on affiche dans le console la chaîne de caractères `"La carte"`
+	> _**NB1 :** Pour afficher une balise qui est en `display:none`, vous pouvez remplacer la valeur du style `display` par `''` (chaîne vide)._
 
-	***NB :** Pour information, le type de `event.currentTarget` est `EventTarget` et celui de la valeur retournée par la méthode `querySelectorAll()` est `NodeList<HTMLElement>`*
-4. **Ajoutez la classe CSS "active" sur la balise `<li>` qui contient le lien qui a été cliqué** (utilisez pour cela la propriété [element.parentElement](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement))
-5. **Juste avant d'ajouter la classe "active" sur le lien cliqué, effacez les classes CSS du `<li>` du menu qui était précédemment actif** de manière à n'avoir qu'un seul lien actif à la fois<br><img src="./images/readme/pizzaland-nav.gif">
+	> _**NB2 :** Pour manipuler les styles vous pouvez aussi utiliser la propriété [`myElement.style` _(mdn)_](https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Using_dynamic_styling_information#modify_an_element_style) qui permet d'agir sur l'attribut `style="..."` de manière un peu plus simple._
 
-## C.3. Navigation en JS
-Il existe plusieurs façons de gérer la navigation en JS.
+	> _**NB3 :** Plus "bourrin" mais qui peut fonctionner aussi dans ce cas là, il existe aussi une méthode [`myElement.removeAttribute()` _(mdn)_](https://developer.mozilla.org/fr/docs/Web/API/Element/removeAttribute)..._
 
-On peut soit générer du code HTML entièrement en JS et l'injecter dans la page (comme on le fait pour la `HomePage`) soit se contenter d'afficher/masquer des portions de la page déjà présentes dans le code html. **C'est cette deuxième technique que l'on va maintenant travailler.**
+	<img src="images/readme/newscontainer.png" >
 
-1. Inspectez le code du fichier `index.html` : vous remarquerez qu'à la fin de la balise `<header>` se trouve une balise masquée (`display:none`) :
-	```html
-	<section class="newsContainer" style="display:none">...</section>
+3. A**u clic sur le bouton `<button class="closeButton"></button>` (_contenu dans la section_) masquez à nouveau le bandeau de news.**
+
+
+## C.2. Navigation en JS : Le menu
+
+La technique de navigation vue à l'instant (_masquer/afficher des balises_) est pratique pour des applications simples, où tout le contenu HTML est déjà généré côté serveur (_en JAVA, en PHP, en C# ou encore avec Node.JS_). \
+**En revanche elle n'est pas très adaptée aux SPA où en général on a du contenu dynamique à injecter dans la page.**
+
+On va donc revenir à la principale technique de navigation employée dans les SPA, celle que l'on utilisait jusque là : **générer dynamiquement, en JS, le code HTML de la page en fonction de ce que demande l'utilisateur** (_comme on le faisait avec la `PizzaList` par exemple_).
+
+Pour approfondir cette technique de navigation et **permettre de passer d'une page à une autre**, je vous propose de nous appuyer sur la classe `Router` que vous avez développée lors du précédent TP ([TP2 / D.3. Propriétés et méthodes statiques : La classe Router](https://gitlab.univ-lille.fr/js/tp2/-/blob/master/D-poo-avancee.md#d3-propri%C3%A9t%C3%A9s-et-m%C3%A9thodes-statiques-la-classe-router)) et dont ma version se trouve dans ce repo (`src/Router.js`).
+
+**L'objectif de l'exercice ici est simple : faire en sorte que lorsque l'utilisateur clique sur un des liens du menu, on affiche un contenu différent dans la page grâce à la méthode `Router.navigate()`.**
+
+<img src="images/readme/nav-simple.gif">
+
+1. **Dans `src/main.js`, commencez par créez des `Component` pour les différents liens du menu :**
+
+	```js
+	const pizzaList = new PizzaList([]),
+		aboutPage = new Component('section', null, 'Ce site est génial'),
+		pizzaForm = new Component('section', null, 'Ici vous pourrez ajouter une pizza');
 	```
-2. Dans `main.js` rendez cette section visible à l'écran à l'aide de la méthode `setAttribute()`. <br>
-	*En CSS, pour afficher une balise qui est en `display:none`, on peut remplacer la valeur du style `display` par `initial`.*
-3. Faites en sorte qu'au clic sur le bouton `<button class="closeButton">` (contenu dans la section) la section soit à nouveau masquée
+	> _**NB1 :** `pizzaList` existe déjà, on ajoute ici juste `aboutPage` et `pizzaForm`._
+
+	> _**NB2 :** pour le moment on utilise pour ces 2 nouvelles pages des `Component` très simples, "en dur", mais on les passera dans des classes spécifiques plus tard._
+
+	**Puis ajoutez les routes correspondantes dans notre Router :**
+	```js
+	Router.routes = [
+		{ path: '/', page: pizzaList, title: 'La carte' },
+		{ path: '/a-propos', page: aboutPage, title: 'À propos' },
+		{ path: '/ajouter-pizza', page: pizzaForm, title: 'Ajouter une pizza' },
+	];
+	```
+
+2. **Pour détecter le clic sur les liens du menu, plutôt que de mettre le code dans le `main.js`, on va déléguer ce travail au `Router`.**
+
+	> _**NB :** Faire ça dans le `Router` permet de **centraliser** tout ce qui concerne la navigation : la détection du clic + le mécanisme de changement de page en lui-même (`Router.navigate()`). Quelle bonne idée !_
+
+	Dans le `src/main.js`, ajoutez la ligne suivante :
+
+	```js
+	Router.menuElement = document.querySelector('.mainMenu');
+	```
+	> _**NB :** en faisant cela on envoie au Router une **référence vers la balise `<ul class="mainMenu">`** qui contient le menu de navigation (cela nous évitera de faire référence à `document` dans la classe `Router` et en plus ça reste cohérent avec le fonctionnement des propriétés `titleElement` et `contentElement`)_
+
+	Router.menuElement est en fait un "setter" dont je vous fourni le code de base à compléter (_à coller **dans** le corps de la classe `Router`_) :
+	```js
+	#menuElement;
+	static set menuElement(element) {
+		this.#menuElement = element;
+		// au clic sur n'importe quel lien contenu dans "element"
+		// déclenchez un appel à Router.navigate(path)
+		// où "path" est la valeur de l'attribut `href=".."` du lien cliqué
+	}
+	```
+
+	À l'aide de ce setter, **détectez le clic sur n'importe quel lien du menu** (_actuellement il n'y a en a que 3, mais votre code doit fonctionner quelque soit le nombre de liens_) et **affichez dans la console l'attribut `href` du lien qui a été cliqué**. \
+	Par exemple si l'utilisateur clique sur le lien **"À propos"** la console doit afficher la chaîne de caractères **`"/a-propos"`**
+
+	> _**NB1 :** vous aurez besoin pour celà de la propriété [`event.currentTarget` _(mdn)_](https://developer.mozilla.org/fr/docs/Web/API/Event/currentTarget) et de la méthode [`element.getAttribute()` _(mdn)_](https://developer.mozilla.org/fr/docs/Web/API/Element/getAttribute)_
+
+	> _**NB2 :** en cas de **problème de scope**, relisez donc la fin du paragraphe [C.1. Rappels](#c1-rappels), juste au cas où..._
+
+3. **Pour terminer, maintenant que vous avez récupéré le `href` du lien cliqué, il ne vous reste plus qu'à invoquer la méthode `Router.navigate()` en lui passant en paramètre le `href` en question !**
+
+	> _**NB :** Là aussi, si vous avez des difficultés à appeler `Router.navigate()` pour des questions **de scope**, relisez la fin du paragraphe [C.1. Rappels](#c1-rappels)..._
+
+	Vérifiez que votre code fonctionne : quand l'utilisateur clique sur un lien du menu, **le contenu de la route correspondante doit s'afficher dans la page !**
+
+
 
-## Étape suivante
-Maintenant que l'on est capable de détecter les actions de l'utilisateur nous allons travailler sur la gestion des formulaires : [D. Les formulaires](./D-formulaires.md).
\ No newline at end of file
+## Étape suivante <!-- omit in toc -->
+Maintenant que l'on est capable de détecter les actions de l'utilisateur et de modifier la page HTML en conséquence, attaquons nous à la gestion des formulaires : [D. Les formulaires](./D-formulaires.md).
\ No newline at end of file
diff --git a/D-formulaires.md b/D-formulaires.md
index 83efa92e23836d5b83bf220a04d7ac0bb6e41af6..435b720bb795fec7a6183607cfda20e9cee0522b 100644
--- a/D-formulaires.md
+++ b/D-formulaires.md
@@ -1,153 +1,158 @@
-#### TP3 - API DOM <!-- omit in toc -->
+<img src="images/readme/header-small.jpg" >
+
 # D. La gestion des formulaires <!-- omit in toc -->
 
+_**Dans cette partie du TP, nous allons travailler sur les formulaires et créer la page d'ajout de pizza (`pizzaForm`)**_
+
 ## Sommaire <!-- omit in toc -->
-- [D.1. Rappels](#d1-rappels)
-- [D.2. Préparatifs](#d2-préparatifs)
+- [D.1. Un peu de théorie](#d1-un-peu-de-théorie)
+- [D.2. Préparatifs : La classe `Page`](#d2-préparatifs-la-classe-page)
 - [D.3. Le formulaire d'ajout de pizza](#d3-le-formulaire-dajout-de-pizza)
 - [D.4. La validation de la saisie](#d4-la-validation-de-la-saisie)
-- [D.5. Le formulaire complet :](#d5-le-formulaire-complet-)
 - [Étape suivante](#étape-suivante)
 
-## D.1. Rappels
-Comme vu en cours (cf. pdf sur moodle), on peut utiliser l'API DOM avec les formulaires principalement pour 2 choses :
-- détecter les changements de valeurs dans les champs de saisie et afficher des messages d'erreur si besoin
-- détecter la soumission du formulaire (pour envoyer des données en AJAX par exemple)
+## D.1. Un peu de théorie
+_**On utilise généralement l'API DOM avec les formulaires pour 2 choses :**_
+1. **Récupérer les valeurs saisies par l'utilisateur** (_et afficher des messages d'erreur par exemple_)
+2. **Détecter la soumission du formulaire** (_pour envoyer des données en AJAX à un webservice par exemple_)
+
+En imaginant le formulaire suivant :
+```html
+<form>
+    <input type="text" name="message">
+    <input type="submit" value="Valider">
+</form>
+```
+On peut lire la valeur tapée par l'utilisateur dans le champ `"message"` avec la propriété [`.value`](https://developer.mozilla.org/fr/docs/Web/HTML/Element/Input#value) de l'élément `<input type="text">`, et l'événement [`submit`](https://developer.mozilla.org/fr/docs/Web/API/HTMLFormElement/submit_event_) de la balise `<form>` :
+```js
+const form = document.querySelector('form'),
+	input = form.querySelector('input[name=message]');
+
+form.addEventListener('submit', function(event) {
+	event.preventDefault();
+	console.log('Le formulaire a été soumis avec la valeur :'+input.value);
+});
+```
+
+## D.2. Préparatifs : La classe `Page`
 
-## D.2. Préparatifs
-**Avant d'aller plus loin dans le TP faisons un point sur le code qui est fourni dans ce repo** : il contient en effet des classes qui correspondent à la solution du précédent TP [D. POO avancée](https://gitlab.univ-lille.fr/js/tp2/blob/master/D-poo-avancee.md) :
+**Avant que vous ne codiez, il faut qu'on parle !**
 
-- **La classe `js/pages/Page.js`** est une classe de base dont hériterons les pages de notre application et qui implémente juste une méthode `renderTitle()`. cette méthode `renderTitle()` retourne le titre de la page (passé dans le constructeur sous forme de chaîne de caractères).
-- **La classe `js/pages/HomePage.js`** hérite de `Page` et permet d'afficher une liste de pizzas passées soit au constructeur, soit à un setter `homePage.pizzas = ...`. Mettre à jour la liste des pizzas via le setter a pour effet de re-générer le tableau des children de la page.
-- **La classe `js/components/PizzaThumbnail.js`** est une classe qui hérite de `Component` et qui permet d'afficher une pizza. Elle est utilisée dans `HomePage`.
-- **Enfin la classe `js/PageRenderer.js`** est une classe qui dispose d'une méthode statique `PageRenderer.renderPage( page )` qui est appelée dans le `main.js`. Cette méthode statique permet d'afficher une page avec son contenu (méthode `page.render()`) et son titre (méthode `page.renderTitle()`).
+**Vous allez coder votre formulaire d'ajout de pizza dans une classe à part, `PizzaForm` (comme on l'a fait pour la `PizzaList`). Et dans cette nouvelle classe il faudra détecter la soumission du formulaire grâce à l'évènement `submit`** (_comme dans l'exemple ci-dessus_).
 
-Si vous ne l'avez pas déjà fait consultez le code de ces fichiers.
+Hors pour le moment, les "pages" de notre application (_comme la `PizzaList`, ou notre future `PizzaForm`_) **ne sont pas capables d'ajouter des écouteurs d'événements** sur le code HTML qu'elles génèrent. \
+**Pourquoi ?** Et bien parce que leur méthode `render()` ne fait que retourner une chaîne de caractères et c'est le `Router` qui se charge de l'ajouter dans le DOM. La page n'a donc aucune connaissance ni du DOM, ni du moment où le code HTML qu'elle a généré est ajouté à l'écran. 😢
 
-***Maintenant que les présentations sont faites, adaptons un peu le code pour préparer la suite du TP :***
+Ce que je vous propose c'est d'ajouter une nouvelle méthode (`mount(element)`) qui va permettre au `Router` d'indiquer à chaque page quelle est la balise HTML (_l'élément du DOM_) dans laquelle elle vient de s'afficher : **de cette manière les pages auront d'un seul coup deux infos : le fait qu'elles viennent d'être affichée à l'écran, et aussi dans quelle balise HTML !**
 
-Pour permettre à chaque page de réagir aux événements de l'utilisateur, on va ajouter une méthode `mount()` dans la classe `Page` et qui sera appelée par la classe `PageRenderer` à chaque fois qu'on affiche une page via `renderPage()` :
+C'est grâce à ces deux infos que nos pages pourront enfin **ajouter des écouteurs d'événement !**
 
-1. **Ajouter la méthode `mount()`** dans la classe `Page` :
+1. **Pour commencer, créez une classe `src/pages/Page.js` qui servira de base à chaque page de l'application :**
+	> _**NB1 :** On aurait pu mettre ça dans la classe `Component` mais ça n'est pas une super idée d'alourdir cette classe avec une méthode qui va servir à quelques instances seulement. Autant en faire une à part._
 	```js
-	mount(element) {
-		// Cette méthode sera appelée par PageRenderer après chaque render()
-		// par défaut, cette méthode ne fait rien
-		// ce sont les classes filles qui devront surcharger cette méthode
+	import Component from '../components/Component';
+
+	export default class Page extends Component {
+		element;
+
+		constructor(className, children) {
+			super('section', { name: 'class', value: className }, children);
+		}
+		mount(element) {
+			this.element = element;
+		}
 	}
 	```
-2. **Appeler la méthode `mount()`** à la fin de la méthode statique `PageRenderer.renderPage()` :
+	> _**NB2 :** Comme vous le voyez la classe `Page` ajoute à la classe `Component` :_
+	> - _une **propriété `element`**_
+  	> - _une **méthode `mount()`** qui se contente de stocker la valeur de `element`_\
+	> _C'est cette méthode qui pourra être surchargée par les pages pour ajouter des écouteurs d'événements_
+
+2. **Faites hériter la `PizzaList` de la classe `Page`, et adaptez le constructeur pour respecter le nouveau constructeur parent** (_celui de `Page` désormais_) :
+
 	```js
-	static renderPage(page) {
-		// ...
-		page.mount(this.contentElement);
+	import Page from './Page';
+	export default class PizzaList extends Page {
+		#pizzas;
+
+		constructor(pizzas) {
+			super('pizzaList');// on pase juste la classe CSS souhaitée
+			this.pizzas = pizzas;
+		}
+		//.. suite de la classe
 	}
 	```
+3. **Dans le `Router`, juste APRÈS avoir fait le `render()` de la page, appelez la méthode `mount()` en lui envoyant l'élément HTML dans lequel elle vient de s'afficher :**
+	```js
+	route.page.mount?.(this.contentElement);
+	```
+
+	> _**NB :** Vous remarquerez qu'on utilise un **opérateur un peu particulier : `?.`**_
+	>
+	> _Il s'agit de l'**[optional chaining operator (mdn)](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Op%C3%A9rateurs/Optional_chaining)** qui permet d'éviter de tester manuellement si ce qui se trouve avant l'opérateur existe. C'est d'ailleurs un concept qui existe dans beaucoup de langages (C#, Python, PHP, Ruby, ...), parfois sous le nom de ["Safe navigation operator" (wikipedia)](https://en.wikipedia.org/wiki/Safe_navigation_operator)._
+	>
+	> _Cette notation est en fait un raccourci pour écrire :_
+	> ```js
+	> if (route.page.mount) {
+	> 	route.page.mount(this.contentElement)
+	> }
+	> ```
 
-**Ces deux modifications faites, passons à la création du formulaire d'ajout de pizza.**
+**Ces modifications faites, nous sommes maintenant prêts à passer à la création du formulaire d'ajout de pizza.**
 
 ## D.3. Le formulaire d'ajout de pizza
-1. **Créez la classe `AddPizzaPage`** (dans un module `js/pages/AddPizzaPage.js`) :
+1. **Créez la classe `PizzaForm`** (dans un module `src/pages/PizzaForm.js`) :
 	```js
 	import Page from './Page.js';
 
 	export default class AddPizzaPage extends Page {
-		constructor() {
-			super('Ajouter une pizza');
-		}
-
 		render() {
 			return /*html*/ `
-				<form class="addPizzaPage">
+				<form class="pizzaForm">
 					<label>
 						Nom :
-						<input type="text" name="nom" class="form-control">
+						<input type="text" name="name">
 					</label>
-					<button type="submit" class="btn btn-default">Ajouter</button>
+					<button type="submit">Ajouter</button>
 				</form>`;
 		}
 
-		mount(element) {}
+		mount(element) {
+			super.mount(element);
+		}
 
 		submit(event) {}
 	}
-
 	```
-
-	***NB :** le commentaire `/*html*/` juste avant la chaîne dans la méthode `render()` permet à l'extension de vscodium "es6-string-html" (que vous avez installé lors du précédent TP) d'appliquer la coloration syntaxique au code html contenu dans la template string, ce qui peut être pratique pour s'y retrouver.*
-
-2. Affichez la page `AddPizzaPage` lors du clic sur le lien du menu `"Ajouter une Pizza"` et la `HomePage` lors du clic sur le lien `"La carte"` et sur le logo.
-
-3. **Dans la méthode `mount()` de la classe `AddPizzaPage`** ajoutez un écouteur d'événement 'submit' sur la balise `<form class="addPizzaPage">`. Cet écouteur d'événement devra déclencher la méthode `submit()` de l'instance.
-
-	***NB :** Pour rappel, la valeur du `this` à l'intérieur d'un écouteur d'événement (fonction appelée par addEventListener) est toujours l'élément HTML qui a déclenché l'événement (ici le formulaire). Pour pouvoir appeler une méthode de l'instance, il faut forcer la valeur du `this` pour qu'elle corresponde toujours à l'instance dans laquelle le code s'exécute. Comme expliqué dans le pdf du cours, il existe plusieurs manières de le faire, mais celle que je vous recommande est l'emploi de la méthode [`bind()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) dans le constructeur de la classe :*
+2. **Utilisez cette classe pour créer la constante `pizzaForm` dans le `main.js`.** À la place de :
 	```js
-	class MaClasse {
-		constructor(){
-			this.onClick = this.onClick.bind(this)
-		}
-		onClick(event) {
-			// this est correct !
-		}
-	}
+	const pizzaList = new PizzaList([]),
+		aboutPage = new Component('p', null, 'ce site est génial'),
+		pizzaForm = new Component('p', null, 'ici vous pourrez ajouter une pizza');
 	```
-4. **Implémentez la méthode `submit()` dans la classe `AddPizzaPage`.**  : cette méthode va pour le moment juste afficher un message dans la console.
+	vous aurez maintenant :
 	```js
-	submit(event) {
-	  // ici le code de votre méthode
-	}
+	const pizzaList = new PizzaList([]),
+		aboutPage = new Component('p', null, 'ce site est génial'),
+		pizzaForm = new PizzaForm();
 	```
-	***NB:** Souvenez vous de la méthode `event.preventDefault()` et vérifiez que la soumission du formulaire n'entraîne pas un rechargement de page...*
 
+	À ce stade, si vous cliquez sur le bouton "Ajouter une pizza" du menu, vous devez voir le formulaire s'afficher :
 
-## D.4. La validation de la saisie
-1. **Au submit, afficher dans la console la valeur saisie par l'utilisateur dans le champ "nom"**. Un sélecteur CSS qui peut être utile ici est le [sélecteur d'attributs](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors).
+	<img src="images/readme/pizzaform.png" >
 
-2. **Si le champ "nom" est vide, afficher un message d'erreur** à l'aide de la fonction [`alert()`](https://developer.mozilla.org/fr/docs/Web/API/Window/alert)
+3. **Dans la méthode `mount()` de la classe `PizzaForm` détectez la soumission du formulaire à l'aide des méthodes `querySelector` et `addEventListener`**. Cet écouteur d'événement devra déclencher l'appel à la méthode `submit()` de l'instance.
 
-3. **Si le champ "nom" n'est pas vide, afficher une alerte "La pizza xxxxx a été ajoutée"** (où "xxxxx" correspond au nom qu'a saisi l'utilisateur) **et vider le champ de saisie** pour permettre à l'utilisateur de saisir une nouvelle pizza.
+	> _**NB :** Souvenez vous de la méthode `event.preventDefault()` et vérifiez que la soumission du formulaire n'entraîne pas un rechargement de page par exemple avec l'onglet Network/Réseau des devtools_
 
-## D.5. Le formulaire complet :
-1. Coder le formulaire complet de création de pizza selon le code HTML suivant (tous les champs sont obligatoires) :
-```html
-<form class="addPizzaPage">
-	<label>
-		Nom :
-		<input type="text" name="nom" class="form-control">
-	</label>
-	<label>
-		Base :
-		<select name="base" class="form-control">
-			<option>Tomate</option>
-			<option>Crème</option>
-		</select>
-	</label>
-	<label>
-		Image :
-		<input type="text" name="image" class="form-control" placeholder="https://...">
-	</label>
-	<label>
-		Prix petit format :
-		<input type="number" name="prix_petite" class="form-control" step="0.05">
-	</label>
-	<label>
-		Prix grand format :
-		<input type="number" name="prix_grande" class="form-control" step="0.05">
-	</label>
-	<label>
-		Ingrédients :
-		<select name="ingredients" multiple="true" class="form-control">
-			<option value="1">Mozzarella</option>
-			<option value="2">Jambon</option>
-			<option value="3">Champignon</option>
-			<option value="4">Olives</option>
-		</select>
-	</label>
-	<button type="submit" class="btn btn-default">Ajouter</button>
-</form>
-```
+4. Au submit, **affichez dans la console la valeur saisie par l'utilisateur dans l'input "name"**.
+
+	> _**NB :** pour sélectionner un champ de formulaire, en général on s'appuie sur le [sélecteur d'attributs](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors) pour sélectionner le champ en fonction de son attribut `name="..."` (comme dans l'exemple vu au chapitre [D.1. Un peu de théorie](#d1-un-peu-de-théorie))._
+
+## D.4. La validation de la saisie
+1. **Si le champ "name" est vide, afficher un message d'erreur** à l'aide de la fonction [`alert()`](https://developer.mozilla.org/fr/docs/Web/API/Window/alert)
 
-***NB:** Pour récupérer la valeur contenue dans un champ `<select>` ce n'est pas la propriété `value` qu'il faut utiliser mais `selectedOptions` (https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/selectedOptions). Cette propriété retourne un tableau des valeurs sélectionnées, si le tableau est vide, c'est qu'aucune valeur n'a été choisie par l'utilisateur.*
+3. **Si le champ "name" n'est pas vide, afficher une alerte "La pizza xxxxx a été ajoutée"** (où "xxxxx" correspond au nom qu'a saisi l'utilisateur) **et videz le champ de saisie** pour permettre à l'utilisateur de saisir une nouvelle pizza.
 
 ## Étape suivante
-Pour terminer, voyons comment intégrer ce que saisit l'utilisateur dans le reste de l'application : [E. Formulaires et navigation](./E-navigation.md).
\ No newline at end of file
+Pour terminer ce TP, voyons comment améliorer la navigation dans notre application à l'aide de la History API : [E. Navigation avancée](./E-navigation-avancee.md).
\ No newline at end of file
diff --git a/E-navigation-avancee.md b/E-navigation-avancee.md
new file mode 100644
index 0000000000000000000000000000000000000000..4c2b002257b16455ae7f1ba07db768a58600f0a3
--- /dev/null
+++ b/E-navigation-avancee.md
@@ -0,0 +1,89 @@
+<img src="images/readme/header-small.jpg" >
+
+# E. Navigation avancée  <!-- omit in toc -->
+
+_**Pour terminer ce TP, nous allons finaliser le mécanisme de navigation dans la page :**_
+- les liens du menu doivent indiquer sur quelle page on se trouve
+- on doit pouvoir utiliser les boutons précédent/suivant du navigateur
+- lorsqu'on recharge la page dans le navigateur (F5) on doit afficher la page sur laquelle l'utilisateur se trouvait
+
+## Sommaire <!-- omit in toc -->
+- [E.1. Mise à jour de la liste](#e1-mise-à-jour-de-la-liste)
+- [D.5. Le formulaire complet :](#d5-le-formulaire-complet-)
+- [E.2. Formulaire d'ingrédients](#e2-formulaire-dingrédients)
+
+## E.1. activation du menu
+**Actuellement lorsqu'on clique sur un lien du menu, rien n'indique dans le menu sur quelle page on se trouve.** On va donc remédier à ça en ajoutant une **classe CSS** sur le lien qui correspond à la page sur laquelle on se rend (_notez le trait plus grand sur le lien cliqué_) :
+
+<img src="./images/readme/nav-active.gif">
+
+**Dans la méthode `Router.navigate()` :**
+1. **ajoutez la classe CSS "active"** sur la balise `<a>` qui correspond au `path` passé à `Router.navigate()`
+
+	> _**NB :** Pour simplifier le travail, plutôt que d'utiliser l'instruction `setAttribute('class', ...)` **je vous recommande plutôt la propriété [`element.classList` (_mdn)_](https://developer.mozilla.org/fr/docs/Web/API/Element/classList) et ses méthodes `element.classList.add()` et `element.classList.remove()`** qui permettent de ne pas se soucier des autres classes CSS déjà présentes sur les balises en plus de la classe `"active"`_
+
+2. **enlevez la classe `"active"` sur le précédent lien actif** (de manière à n'avoir qu'un seul lien actif à la fois)
+
+## E.2. History API
+
+_**Notre SPA commence à ressembler à quelque chose mais souffre encore d'un GROS PROBLÈME par rapport à une application web "classique" (celles avec rechargement de page) : impossible d'utiliser les boutons précédent/suivant du navigateur !**_
+
+Heureusement il existe une API JS qui va nous permettre de résoudre ce problème : **la [History API (mdn)](https://developer.mozilla.org/fr/docs/Web/Guide/DOM/Manipuler_historique_du_navigateur)** .\
+Cette API est un ensemble de méthodes de l'objet `window`, disponibles de base, et qui permettent de **manipuler l'URL dans la barre d'adresse du navigateur SANS rechargement de page** !
+
+Quand l'utilisateur change de page (_pour passer de la liste au formulaire par exemple_) on va pouvoir modifier, en JS, l'url courante :
+
+<img src="images/readme/changement-url.gif" />
+
+Ce qui permet ensuite d'utiliser les boutons précédent/suivant du navigateur (_là aussi sans rechargement de page_) :
+
+<img src="images/readme/boutons-prev-next.gif" />
+
+1. **Dans la méthode `Router.navigate()`, appelez [`window.history.pushState()` _(mdn)_](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState) pour modifier l'URL de la page.**
+
+	> _**NB :** Si vous lisez la documentation en détail vous verrez qu'au final peu importe la valeur des 2 premiers paramètres de `pushState()` (ils peuvent être `null`), c'est surtout le 3e qui est important._
+
+2. **L'URL change maintenant à chaque fois que vous cliquez sur un lien du menu, mais si vous utilisez les boutons précédent/suivant du navigateur, vous verrez que rien ne se passe.** Il reste en effet à détecter le changement d'URL dans notre code pour **invoquer `Router.navigate()` à chaque fois que l'utilisateur utilise les boutons précédent/suivant**.
+
+	Pour celà nous avons à notre disposition 2 outils :
+	- le **callback [`window.onpopstate` _(mdn)_](https://developer.mozilla.org/fr/docs/Web/API/WindowEventHandlers/onpopstate)** qui permet d'appeler une fonction lors de l'utilisation des boutons précédent/suivant du navigateur
+	- et la **propriété [`document.location` _(mdn)_](https://developer.mozilla.org/fr/docs/Web/API/Document/location)** qui permet d'obtenir des informations sur l'URL de la page courante
+
+	Dans `src/main.js`, assignez une fonction (un arrow function par exemple) à `window.onpopstate` et placez-y pour le moment juste un `console.log(document.location)`.
+
+	Rechargez la page, naviguez un peu via le menu et les boutons précédent/suivant et inspectez dans la console le contenu de `document.location`, vous devriez y trouver quelque chose qui peut vous aider à afficher la bonne page...
+
+	> _**NB :** faites attention à ne pas invoquer `window.history.pushState()` lors du `onpopstate` sinon cela va quelque peu "casser" la navigation avec les boutons précédent/suivant en créant une "inception"..._
+
+
+## E.3. Le Deeplinking
+
+_**Notre application est presque terminée, à un détail près : l'absence de [deep linking](https://fr.wikipedia.org/wiki/Lien_profond).**_
+
+En effet, si vous vous rendez directement sur http://localhost:8000/a-propos dans votre navigateur (_sans passer par la racine_), le serveur vous retourne une erreur 404 à la place de la page de détail.
+
+<img src="images/readme/404.gif" />
+
+En fait, lorsque vous lancez la requête en entrant cette URL dans la barre d'adresse du navigateur, le serveur http lancé avec `npx serve` cherche par défaut à trouver un fichier `a-propos.html` ou bien un fichier `index.html` dans un sous dossier `/a-propos/`. Autant dire que ça n'a aucune chance de fonctionner comme ça.
+
+Heureusement `npx serve` dispose d'une option `-s` qui permet de rediriger toutes les 404 vers le `index.html` de la racine : ainsi notre JS se chargera et il ne restera plus qu'à déterminer (en JS) quelle page afficher grâce à l'URL courante.
+
+1. **Stoppez le serveur HTTP `npx serve -l 8000` et relancez le avec cette fois l'option `-s` :**
+	```bash
+	npx serve -s -l 8000
+	```
+	Rechargez la page http://localhost:8000/a-propos : la 404 a disparu est le site s'affiche ! Malheureusement c'est encore la `PizzaList` qui est affichée et pas la page "À propos"...
+
+2. **Maintenant que notre site s'affiche quelque soit l'URL de la page, reste à faire en sorte que l'on affiche la page qui correspond à l'URL demandée par l'utilisateur.**
+
+	Actuellement, au chargement, notre application affiche toujours la `PizzaList` en premier car dans notre `main.js` nous avons le code :
+	```js
+	Router.navigate('/');
+	```
+	La solution est simple : il suffit de remplacer cette URL en dur (`'/'`) par l'URL de la page courante.
+
+	Ça tombe bien, dans l'exercice précédent vous avez découvert la propriété qui permet de récupérer l'URL courante de la barre d'adresse. Ne reste plus qu'à envoyer cette valeur au `Router.navigate()` initial et le tour est joué !
+
+_**À partir de maintenant, vous pouvez en principe charger le site depuis n'importe quelle URL ! Youpi. Merci le deep linking !**_
+
+<img src="images/readme/deeplinking.gif" />
diff --git a/E-navigation.md b/E-navigation.md
deleted file mode 100644
index 661cd18f42edfb5847d2b0044c249ef76d7270f0..0000000000000000000000000000000000000000
--- a/E-navigation.md
+++ /dev/null
@@ -1,19 +0,0 @@
-#### TP3 - API DOM <!-- omit in toc -->
-# E. Formulaires et navigation <!-- omit in toc -->
-
-## Sommaire <!-- omit in toc -->
-- [E.1. Mise à jour de la liste](#e1-mise-à-jour-de-la-liste)
-- [E.2. Formulaire d'ingrédients](#e2-formulaire-dingrédients)
-
-## E.1. Mise à jour de la liste
-Lorsque l'utilisateur soumet le formulaire (et à condition que l'utilisateur n'ait pas fait d'erreur de saisie), faites en sorte que l'on retourne sur la `HomePage` avec la liste des pizzas mise à jour.
-
-## E.2. Formulaire d'ingrédients
-**Ajoutez dans le formulaire `AddPizzaPage` un lien "ajouter un ingrédient".**
-
-Au clic sur ce lien, il faut :
-1. **Afficher un nouveau formulaire à la place de la AddPizzaPage**. Ce formulaire contient uniquement un champ "nom" (obligatoire) et un bouton "submit". (*Vous pouvez vous inspirer vous du code HTML fourni à l'exercice [C.3. Le formulaire d'ajout de pizza](./C-formulaires.md#c3-le-formulaire-dajout-de-pizza)*)
-2. Lors de la soumission du formulaire (si pas d'erreur), **ré-afficher la `AddPizzaPage` avec la liste des ingrédients mise à jour** avec le nouvel ingrédient saisi par l'utilisateur.
-3. Faire en sorte que les champs du formulaire `AddPizzaPage` soient pré-remplies avec les valeurs précédentes :<br>
-	Si l'utilisateur avait par exemple déjà renseigné un nom pour sa pizza avant de cliquer sur le lien "ajouter un ingrédient", lorsqu'il a terminé d'ajouter son ingrédient et qu'il retourne sur la `AddPizzaPage`, le formulaire doit se ré-afficher avec le nom de pizza qu'il avait précédemment saisi.
-
diff --git a/css/pizzaForm.css b/css/pizzaForm.css
new file mode 100644
index 0000000000000000000000000000000000000000..e27f380711a551d28a66596da722976b765048b5
--- /dev/null
+++ b/css/pizzaForm.css
@@ -0,0 +1,64 @@
+.pizzaForm {
+	background: white;
+    padding: 50px;
+    border: 1px #13181919 solid;
+    outline: 20px hsl(240deg 0% 100%) solid;
+	margin: 20px;
+	margin-bottom: 50px;
+	display: flex;
+	flex-direction: column;
+	align-items: flex-start;
+}
+.pizzaForm button[type="submit"] {
+	align-self: center;
+	margin-top: 30px;
+	border: 1px transparent solid;
+	border-radius: 3px;
+	padding: 15px 50px;
+	font-family: OpenSansCondensed;
+	font-size: 18px;
+	letter-spacing: 2px;
+	font-weight: bold;
+	text-transform: uppercase;
+	cursor: pointer;
+	background-color: white;
+	transition: all .15s ease-out;
+	border-color: #131819;
+}
+.pizzaForm button[type="submit"]:hover {
+	background-color: #e2952d;
+	background-color: #131819;
+	border-color: transparent;
+	color: white;
+}
+.pizzaForm label {
+	width: 100%;
+	display: flex;
+	flex-direction: column;
+	font-family: OpenSansCondensed;
+	font-size: 18px;
+	letter-spacing: 2px;
+	font-weight: lighter;
+	text-transform: uppercase;
+}
+.pizzaForm input {
+	border: 1px #eee solid;
+	border-radius: 3px;
+	background-color: #fefefe;
+	padding: 10px 20px;
+	font-size: 16px;
+	margin-top: 5px;
+}
+
+@media (min-width: 1024px) {
+	.pizzaForm {
+		width: 70%;
+		margin-bottom: 150px;
+	}
+	.pizzaForm button[type="submit"] {
+		align-self: flex-end;
+	}
+	.pizzaForm label {
+		/* width: 60%; */
+	}
+}
\ No newline at end of file
diff --git a/images/readme/404.gif b/images/readme/404.gif
new file mode 100644
index 0000000000000000000000000000000000000000..ebba0c518d75803cef17bec2ba4bfe982e65d67b
Binary files /dev/null and b/images/readme/404.gif differ
diff --git a/images/readme/boutons-prev-next.gif b/images/readme/boutons-prev-next.gif
new file mode 100644
index 0000000000000000000000000000000000000000..8eff810b044b90553a44edb810d5e08c94d4596b
Binary files /dev/null and b/images/readme/boutons-prev-next.gif differ
diff --git a/images/readme/changement-url.gif b/images/readme/changement-url.gif
new file mode 100644
index 0000000000000000000000000000000000000000..946f5cfd819028ebf51274c2dad0cf9f53b239e0
Binary files /dev/null and b/images/readme/changement-url.gif differ
diff --git a/images/readme/deeplinking.gif b/images/readme/deeplinking.gif
new file mode 100644
index 0000000000000000000000000000000000000000..ab5325ecb2400f4dfade1ed60c29911c30357e29
Binary files /dev/null and b/images/readme/deeplinking.gif differ
diff --git a/images/readme/nav-active.gif b/images/readme/nav-active.gif
new file mode 100644
index 0000000000000000000000000000000000000000..354ac1408f12fe05eb07a84b96fa4774a096e877
Binary files /dev/null and b/images/readme/nav-active.gif differ
diff --git a/images/readme/nav-simple.gif b/images/readme/nav-simple.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f95e5f418e471e29f3618a31ccf9be2d68814a95
Binary files /dev/null and b/images/readme/nav-simple.gif differ
diff --git a/images/readme/newscontainer.png b/images/readme/newscontainer.png
new file mode 100644
index 0000000000000000000000000000000000000000..9b79588d0c2a25257782ef1a3209d6c9432c6dc3
Binary files /dev/null and b/images/readme/newscontainer.png differ
diff --git a/images/readme/pizzaform.png b/images/readme/pizzaform.png
new file mode 100644
index 0000000000000000000000000000000000000000..0b62518532f043c0124d71e08c145b3abb7d1890
Binary files /dev/null and b/images/readme/pizzaform.png differ
diff --git a/images/readme/pizzaland-innerhtml.png b/images/readme/pizzaland-innerhtml.png
index cd2d1381f71dc8c48e0adc1a62878caa54e582dc..7b3336142c1d5534fb5bd9788487c466a613acfb 100644
Binary files a/images/readme/pizzaland-innerhtml.png and b/images/readme/pizzaland-innerhtml.png differ
diff --git a/images/readme/pizzaland-setattribute.png b/images/readme/pizzaland-setattribute.png
index 467e1b7bbd437d70ecdae15df866b47f171f324e..c2bee3aebcdabd9c6ee5c2b69aacac4d2346f18a 100644
Binary files a/images/readme/pizzaland-setattribute.png and b/images/readme/pizzaland-setattribute.png differ
diff --git a/images/readme/queryselector-console.jpg b/images/readme/queryselector-console.jpg
deleted file mode 100644
index 279edc9106ed3ea924d2f7b4f947327f78e87085..0000000000000000000000000000000000000000
Binary files a/images/readme/queryselector-console.jpg and /dev/null differ
diff --git a/images/readme/queryselector-console.png b/images/readme/queryselector-console.png
new file mode 100644
index 0000000000000000000000000000000000000000..7fddf5199362dbbd8a0d927823456934f9d60f07
Binary files /dev/null and b/images/readme/queryselector-console.png differ
diff --git a/images/readme/queryselector-pizzaList.png b/images/readme/queryselector-pizzaList.png
new file mode 100644
index 0000000000000000000000000000000000000000..d6bade71e2611d69bf948755b2d7caf99a2b298b
Binary files /dev/null and b/images/readme/queryselector-pizzaList.png differ
diff --git a/images/readme/queryselectorall-console.jpg b/images/readme/queryselectorall-console.jpg
deleted file mode 100644
index 664b827366cae14132cb0cf4c440551017fad546..0000000000000000000000000000000000000000
Binary files a/images/readme/queryselectorall-console.jpg and /dev/null differ
diff --git a/images/readme/queryselectorall-console.png b/images/readme/queryselectorall-console.png
new file mode 100644
index 0000000000000000000000000000000000000000..b255cb5048d4a47173546866375e4d6e6a266880
Binary files /dev/null and b/images/readme/queryselectorall-console.png differ
diff --git a/index.html b/index.html
index 21d4d9489ae8bafa7dc479ba05279ea659f884ac..deabf718ff842d73e25378db9d26090d2f8725bc 100644
--- a/index.html
+++ b/index.html
@@ -12,6 +12,7 @@
 	<link rel="stylesheet" href="css/header.css">
 	<link rel="stylesheet" href="css/news.css">
 	<link rel="stylesheet" href="css/pizzaList.css">
+	<link rel="stylesheet" href="css/pizzaForm.css">
 	<link rel="stylesheet" href="css/footer.css">
 
 	<script src="build/main.bundle.js" defer></script>
@@ -30,6 +31,12 @@
 			</ul>
 		</nav>
 	</header>
+	<section class="newsContainer" style="display:none">
+		<article>
+			<button class="closeButton"></button>
+			<h1>Bienvenue chez <strong>Pizza<em>Land</em></strong> !</h1>
+		</article>
+	</section>
 	<section class="pageContainer">
 		<header class="pageTitle"></header>
 		<div class="pageContent"></div>