diff --git a/public/articles/index.json b/public/articles/index.json
new file mode 100644
index 0000000000000000000000000000000000000000..47ee6090ac61be84066d8916c2916490ea40ac44
--- /dev/null
+++ b/public/articles/index.json
@@ -0,0 +1 @@
+["test/article-test.json", "nested/article-nested.json"]
diff --git a/public/articles/nested/article-nested.json b/public/articles/nested/article-nested.json
new file mode 100644
index 0000000000000000000000000000000000000000..8c147f61e8ffe0e4e48892d2aef83892ce07e6ea
--- /dev/null
+++ b/public/articles/nested/article-nested.json
@@ -0,0 +1,7 @@
+{
+    "title": "Kuadrado Software mange des burgers",
+    "date": "1954/02/25",
+    "subtitle": "Ouaiis on est vraiment contents",
+    "content_text": "<file>my-content-text.txt",
+    "images": ["screen_1.png", "screen_2.png", "screen_3.png", "screen_4.png"]
+}
diff --git a/public/articles/nested/images/screen_1.png b/public/articles/nested/images/screen_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..587547fe68e89af126f12a84b26d1ae2b3d159fa
Binary files /dev/null and b/public/articles/nested/images/screen_1.png differ
diff --git a/public/articles/nested/images/screen_2.png b/public/articles/nested/images/screen_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..c470a68727dba88945d2b1e85ed90e627dec6345
Binary files /dev/null and b/public/articles/nested/images/screen_2.png differ
diff --git a/public/articles/nested/images/screen_3.png b/public/articles/nested/images/screen_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..c3e25291c40fb8d02022e5782b6c80d51c239ed7
Binary files /dev/null and b/public/articles/nested/images/screen_3.png differ
diff --git a/public/articles/nested/images/screen_4.png b/public/articles/nested/images/screen_4.png
new file mode 100644
index 0000000000000000000000000000000000000000..72f302b5873aa1237c9f6372daa463b598cd654c
Binary files /dev/null and b/public/articles/nested/images/screen_4.png differ
diff --git a/public/articles/nested/my-content-text.txt b/public/articles/nested/my-content-text.txt
new file mode 100644
index 0000000000000000000000000000000000000000..135ddb638142538d9698298319dcf5b80b93fb90
--- /dev/null
+++ b/public/articles/nested/my-content-text.txt
@@ -0,0 +1,14 @@
+Hahahaha eh ouais c'est encore nous.
+Ben ce coup ci on voulait vous dire que ce soir on va commander des burger, et qu'on va se mater une petite prod hollywoodienne qui devrait nous faire oublier toute cette merde de Covid etc. Enfin bref.
+Bon ben du coup je sais pas, allez bon ap quoi. Ouais salut
+Ok
+
+Ben quoi, ouais jsais pas. Ben non on n'a pas de masque on tient pas à crever asphyxiés.
+Nique le capitalisme. Qu'il crève dans son jus moisi et qu'il revienne pas nous emmerder.
+
+Donc ouais on va en rajouter encore un peu. Donc voilà ben ça fait plus de mots du coup.
+
+Haha et ben tu sais pas ?
+Non ?
+Eh ben rien. 
+Mais ça fait des lignes, comme ça je vois ce qui se passe pour un long article.
\ No newline at end of file
diff --git a/public/articles/test/article-test.json b/public/articles/test/article-test.json
new file mode 100644
index 0000000000000000000000000000000000000000..a2afa7c8e7bafa66610c2a1f65f7b152d40a7ba4
--- /dev/null
+++ b/public/articles/test/article-test.json
@@ -0,0 +1,13 @@
+{
+    "title": "Kuadrado Software ouvre ses portes",
+    "date": "2032/08/25",
+    "subtitle": "Ouaiis on est vraiment contents",
+    "content_text": "<file>content-text.txt",
+    "images": [
+        "screen_l1_1.jpg",
+        "screen_l1_2.jpg",
+        "screen_l2.jpg",
+        "screen_l3.jpg",
+        "screen_secret.jpg"
+    ]
+}
diff --git a/public/articles/test/content-text.txt b/public/articles/test/content-text.txt
new file mode 100644
index 0000000000000000000000000000000000000000..427fa08c7cc5b2437196cbc98323f7ddd6243bea
--- /dev/null
+++ b/public/articles/test/content-text.txt
@@ -0,0 +1,8 @@
+Et ben voilà on est bien contents d'ouvrir nos portes. Nique sa mère le Covid, on lui pisse à la raie.
+Eh ouais, ben ouais.
+Alors voilà on est sympa, puis en plus on est des lapins. Faut bien le dire...
+
+Qu'est-ce qu'on pourrait dire d'autre ? Ben chais pas, on fait des jeux, puis des fois on se gueule dessus, même que les voisins doivent nous prendre pour des cassos des fois... M'enfin.
+
+Ben voilà allez salut !
+hop un petit lien http://example.com||ici
\ No newline at end of file
diff --git a/public/articles/test/images/screen_l1_1.jpg b/public/articles/test/images/screen_l1_1.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..2945b61a5e2126fa10ef10d03310847ffd0f07b1
Binary files /dev/null and b/public/articles/test/images/screen_l1_1.jpg differ
diff --git a/public/articles/test/images/screen_l1_2.jpg b/public/articles/test/images/screen_l1_2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3e234f9d794af420606e2776e53eaa0e93ad1320
Binary files /dev/null and b/public/articles/test/images/screen_l1_2.jpg differ
diff --git a/public/articles/test/images/screen_l2.jpg b/public/articles/test/images/screen_l2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..da9b1091db217b2f58d71e1b2d3026b6b8d2baae
Binary files /dev/null and b/public/articles/test/images/screen_l2.jpg differ
diff --git a/public/articles/test/images/screen_l3.jpg b/public/articles/test/images/screen_l3.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..aa8001610c81567b2048496c1d03f85f66dd243d
Binary files /dev/null and b/public/articles/test/images/screen_l3.jpg differ
diff --git a/public/articles/test/images/screen_secret.jpg b/public/articles/test/images/screen_secret.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..9b2e265692d988f486e212e4ef9cd419c0d50360
Binary files /dev/null and b/public/articles/test/images/screen_secret.jpg differ
diff --git a/public/assets/images/screen_fantom_quest.jpg b/public/assets/images/screen_fantom_quest.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..46582db55da4bc7fdb7eb03774fc184b06e4973b
Binary files /dev/null and b/public/assets/images/screen_fantom_quest.jpg differ
diff --git a/public/education/education.js b/public/education/education.js
index 3e9dae4ad0dc12ab1eee1c32c4912db2590449dd..75582984892951582798ccff04f88e0a44ffb995 100644
--- a/public/education/education.js
+++ b/public/education/education.js
@@ -18,6 +18,7 @@ const { server_url } = require("./config");
 
 module.exports = {
     images_url: `${server_url}/assets/images`,
+    articles_url: `${server_url}/articles`,
 };
 
 },{"./config":1}],3:[function(require,module,exports){
@@ -199,7 +200,7 @@ class GameStudioClub {
                 },
                 {
                     tag: "div",
-                    class: "section-contents",
+                    class: "section-contents page-contents-center",
                     contents: [
                         {
                             tag: "div",
@@ -513,7 +514,7 @@ class Popularization {
                 },
                 {
                     tag: "div",
-                    class: "section-contents",
+                    class: "section-contents page-contents-center",
                     contents: [
                         {
                             tag: "div",
@@ -680,10 +681,10 @@ class EducationPage {
                     tag: "div",
                     class: "page-header",
                     contents: [
-                        { tag: "h1", contents: "<blue>Pédagogie</blue>" },
+                        { tag: "h1", contents: "Pédagogie", class: "page-contents-center" },
                         {
                             tag: "p",
-                            class: "edu-philo",
+                            class: "page-contents-center",
                             contents:
                                 "Démystifier et s'approprier la technologie par le partage de connaissances.",
                         },
diff --git a/public/games/games.js b/public/games/games.js
index 3b0f3b482e5be47530f3bfb529c7b782d6200bc2..64c83346ffc44445a68d9cd9e27dfabdac2b3233 100644
--- a/public/games/games.js
+++ b/public/games/games.js
@@ -18,6 +18,7 @@ const { server_url } = require("./config");
 
 module.exports = {
     images_url: `${server_url}/assets/images`,
+    articles_url: `${server_url}/articles`,
 };
 
 },{"./config":1}],3:[function(require,module,exports){
@@ -119,8 +120,11 @@ class GamesPage {
             tag: "div",
             contents: [
                 {
-                    tag: "h1",
-                    contents: "Games",
+                    tag: "div",
+                    class: "page-header",
+                    contents: [
+                        { tag: "h1", contents: "Jeux", class: "page-contents-center" }
+                    ],
                 },
             ],
         };
diff --git a/public/main.js b/public/main.js
index 6d74ee1fd25196e0fab0a5cc483549767c26de1c..52dabf18c2cff1a0e2b15abaa32c5668e1ae5aa9 100644
--- a/public/main.js
+++ b/public/main.js
@@ -18,11 +18,298 @@ const { server_url } = require("./config");
 
 module.exports = {
     images_url: `${server_url}/assets/images`,
+    articles_url: `${server_url}/articles`,
 };
 
 },{"./config":1}],3:[function(require,module,exports){
 "use strict";
 
+const { articles_url } = require("../../constants");
+const { fetchjson, fetchtext } = require("../lib/fetch");
+const objectHtmlRenderer = require("../lib/object-html-renderer");
+const ImageCarousel = require("./image-carousel");
+
+class Articles {
+    constructor() {
+        this.id = performance.now().toString();
+        this.state = {
+            loading: true,
+            articles: [],
+            showArticleIndex: -1,
+        };
+        this.loadArticles();
+    }
+
+    loadArticles() {
+        fetchjson(`${articles_url}/index.json`)
+            .then(json => {
+                Promise.all(
+                    json.map(async articlePath => {
+                        const art = await fetchjson(`${articles_url}/${articlePath}`);
+                        const tmpSplit = articlePath.split("/");
+                        tmpSplit.pop();
+                        const absArtPath = `${articles_url}/${tmpSplit.join("/")}`;
+                        return Object.assign(art, { path: absArtPath });
+                    })
+                )
+                    .then(articles => this.setArticles(articles))
+                    .catch(e => console.log(e));
+            })
+            .catch(e => console.log(e));
+    }
+
+    async setArticles(articles) {
+        for (const article of articles) {
+            if (article.content_text.indexOf("<file>") !== -1) {
+                const txtPath = article.content_text.replace("<file>", "");
+                const txtValue = await fetchtext(`${article.path}/${txtPath}`);
+                article.content_text = txtValue;
+            }
+            article.date = new Date(article.date);
+        }
+        this.state.articles = articles.sort((a, b) => a.date - b.date);
+        this.state.showArticleIndex = this.state.articles.length - 1;
+        this.refresh();
+    }
+
+    refresh() {
+        objectHtmlRenderer.subRender(this.render(), document.getElementById(this.id), {
+            mode: "replace",
+        });
+    }
+
+    getArticleDate(date) {
+        return `${date.getDate()}-${date.getMonth() + 1}-${date.getFullYear()}`;
+    }
+
+    getArticleBody(text) {
+        return text
+            .split(" ")
+            .map(word => {
+                if (word.includes("http://") || word.includes("https://")) {
+                    const splitword = word.split("||");
+                    const href = splitword[0];
+                    const text = splitword.length > 1 ? splitword[1] : href;
+                    return `<a href=${href} target="_blank">${text}</a>`;
+                } else return word;
+            })
+            .join(" ")
+            .replaceAll("\n", "<br/>");
+    }
+
+    renderArticle(articleData) {
+        return {
+            tag: "article",
+            contents: [
+                {
+                    tag: "div",
+                    class: "date",
+                    contents: [{ tag: "span", contents: this.getArticleDate(articleData.date) }],
+                },
+                {
+                    tag: "div",
+                    class: "title",
+                    contents: [
+                        {
+                            tag: "h3",
+                            contents: articleData.title,
+                        },
+                    ],
+                },
+                {
+                    tag: "div",
+                    class: "subtitle",
+                    contents: [
+                        {
+                            tag: "strong",
+                            contents: articleData.subtitle,
+                        },
+                    ],
+                },
+                {
+                    tag: "div",
+                    class: "body",
+                    contents: [
+                        {
+                            tag: "p",
+                            contents: this.getArticleBody(articleData.content_text),
+                        },
+                    ],
+                },
+                new ImageCarousel({
+                    images: articleData.images.map(img => `${articleData.path}/images/${img}`),
+                }).render(),
+            ],
+        };
+    }
+
+    renderArticlePlaceholder() {
+        return {
+            tag: "article",
+            class: "article-placeholder page-contents-center",
+            contents: [
+                { tag: "div", class: "date" },
+                { tag: "div", class: "title" },
+                { tag: "div", class: "subtitle" },
+                { tag: "div", class: "body" },
+                { tag: "div", class: "image" },
+            ],
+        };
+    }
+
+    handleChangeArticle(dir) {
+        let { showArticleIndex, articles } = this.state;
+        showArticleIndex =
+            dir === "prev"
+                ? showArticleIndex - 1 >= 0
+                    ? showArticleIndex - 1
+                    : 0
+                : showArticleIndex + 1 <= articles.length - 1
+                ? showArticleIndex + 1
+                : articles.length - 1;
+        this.state.showArticleIndex = showArticleIndex;
+        this.refresh();
+    }
+
+    render() {
+        const { articles, showArticleIndex } = this.state,
+            showNext = showArticleIndex < articles.length - 1,
+            showPrev = showArticleIndex > 0;
+        return {
+            tag: "div",
+            id: this.id,
+            class: "articles-displayer page-contents-center",
+            contents:
+                articles.length > 0
+                    ? [
+                          {
+                              tag: "button",
+                              class: `prev-btn ${!showPrev ? "disabled" : "active"}`,
+                              onclick: this.handleChangeArticle.bind(this, "prev"),
+                          },
+                          this.renderArticle(articles[showArticleIndex]),
+                          {
+                              tag: "button",
+                              class: `next-btn ${!showNext ? "disabled" : "active"}`,
+                              onclick: this.handleChangeArticle.bind(this, "next"),
+                          },
+                      ]
+                    : [this.renderArticlePlaceholder()],
+        };
+    }
+}
+
+module.exports = Articles;
+
+},{"../../constants":2,"../lib/fetch":7,"../lib/object-html-renderer":8,"./image-carousel":4}],4:[function(require,module,exports){
+"use strict";
+
+const objectHtmlRenderer = require("../lib/object-html-renderer");
+
+class ImageCarousel {
+    constructor(props) {
+        this.props = props;
+        this.id = performance.now();
+        this.state = {
+            showImageIndex: 0,
+        };
+        this.RUN_INTERVAL = 5000;
+        this.run();
+    }
+
+    run() {
+        this.runningInterval = setInterval(() => {
+            let { showImageIndex } = this.state;
+            const { images } = this.props;
+            this.state.showImageIndex = showImageIndex < images.length - 1 ? ++showImageIndex : 0;
+            this.refreshImage();
+        }, this.RUN_INTERVAL);
+    }
+
+    setImageIndex(i) {
+        clearInterval(this.runningInterval);
+        this.state.showImageIndex = i;
+        this.refreshImage();
+    }
+
+    refreshImage() {
+        objectHtmlRenderer.subRender(this.render(), document.getElementById(this.id), {
+            mode: "replace",
+        });
+    }
+
+    render() {
+        const { showImageIndex } = this.state;
+        const { images } = this.props;
+        return {
+            tag: "div",
+            id: this.id,
+            class: "image-carousel",
+            contents: [
+                { tag: "img", src: images[showImageIndex] },
+                {
+                    tag: "div",
+                    class: "carousel-bullets",
+                    contents: images.map((_, i) => {
+                        const active = showImageIndex === i;
+                        return {
+                            tag: "span",
+                            class: `bullet ${active ? "active" : ""}`,
+                            onclick: this.setImageIndex.bind(this, i),
+                        };
+                    }),
+                },
+            ],
+        };
+    }
+}
+
+module.exports = ImageCarousel;
+
+},{"../lib/object-html-renderer":8}],5:[function(require,module,exports){
+"use strict";
+
+const { images_url } = require("../../constants");
+
+class ThemeCard {
+    constructor(props) {
+        this.props = props;
+    }
+
+    render() {
+        return {
+            tag: "a",
+            class: "theme-card",
+            href: this.props.href,
+            contents: [
+                {
+                    tag: "div",
+                    class: "card-img",
+                    contents: [{ tag: "img", src: `${images_url}/${this.props.img}` }],
+                },
+                {
+                    tag: "div",
+                    class: "card-title",
+                    contents: [{ tag: "h2", class: "section-title", contents: this.props.title }],
+                },
+                {
+                    tag: "div",
+                    class: "card-description",
+                    contents: [{ tag: "p", contents: this.props.description }],
+                },
+            ],
+        };
+    }
+}
+
+module.exports = ThemeCard;
+
+},{"../../constants":2}],6:[function(require,module,exports){
+"use strict";
+
+const Articles = require("./home-page-components/articles");
+const ThemeCard = require("./home-page-components/theme-card");
+
 class HomePage {
     constructor(args) {
         Object.assign(this, args);
@@ -31,10 +318,57 @@ class HomePage {
     render() {
         return {
             tag: "div",
+            id: "home-page",
             contents: [
                 {
-                    tag: "h1",
-                    contents: "Kuadrado Software",
+                    tag: "div",
+                    class: "page-header",
+                    contents: [
+                        { tag: "h1", contents: "Kuadrado Software", class: "page-contents-center" },
+                        {
+                            tag: "p",
+                            class: "page-contents-center",
+                            contents: `<b>Kvadrata rado</b> veut dire "roue carrée" en Esperanto, c'est le symbole que nous avons choisi pour Kuadrado 
+                            pour dire qu'on aime bien fabriquer les trucs nous même, avec des briques aussi élémentaires que possible, 
+                            pour le plaisir de les maîtriser et de les comprendre. Quitte parfois à réinventer un peu la roue.
+                            `,
+                        },
+                    ],
+                },
+                {
+                    tag: "section",
+                    class: "page-contents-center",
+                    contents: [
+                        { tag: "h2", contents: "Actu", class: "section-title bg-blue" },
+                        new Articles().render(),
+                    ],
+                },
+                {
+                    tag: "section",
+                    class: "page-contents-center grid-3",
+                    contents: [
+                        {
+                            title: "Jeux",
+                            img: "screen_fantom_quest.jpg",
+                            href: "/games/",
+                            description:
+                                "Toutes nos créations vidéoludiques, jeux web et jeux PC, projets en cours, c'est par ici que ça se passe.",
+                        },
+                        {
+                            title: "Software",
+                            img: "learning_theme_coding.png",
+                            href: "/software-development/",
+                            description:
+                                "Des fois quand on a besoin d'un outil, on le fabrique nous même (si ça nous amuse) ! Retrouvez les projets en détail.",
+                        },
+                        {
+                            title: "Pédagogie",
+                            img: "popularization_banner.png",
+                            href: "/education/",
+                            description:
+                                "La pédagogie est une arme puissante pour faire tomber les barrières entre les gens et la technologie, et nous sommes bien décidés à en faire usage !",
+                        },
+                    ].map(cardProps => new ThemeCard(cardProps).render()),
                 },
             ],
         };
@@ -43,7 +377,32 @@ class HomePage {
 
 module.exports = HomePage;
 
-},{}],4:[function(require,module,exports){
+},{"./home-page-components/articles":3,"./home-page-components/theme-card":5}],7:[function(require,module,exports){
+"use strict";
+
+function fetchjson(url) {
+    return new Promise((resolve, reject) => {
+        fetch(url)
+            .then(r => r.json())
+            .then(r => resolve(r))
+            .catch(e => reject(e));
+    });
+};
+
+function fetchtext(url) {
+    return new Promise((resolve, reject) => {
+        fetch(url)
+            .then(r => r.text())
+            .then(r => resolve(r))
+            .catch(e => reject(e));
+    });
+};
+
+module.exports = {
+    fetchjson, fetchtext
+}
+
+},{}],8:[function(require,module,exports){
 "use strict";
 
 module.exports = {
@@ -129,7 +488,7 @@ module.exports = {
     },
 };
 
-},{}],5:[function(require,module,exports){
+},{}],9:[function(require,module,exports){
 "use strict";
 
 const HomePage = require("./homepage");
@@ -137,7 +496,7 @@ const runPage = require("./run-page");
 
 runPage(HomePage);
 
-},{"./homepage":3,"./run-page":6}],6:[function(require,module,exports){
+},{"./homepage":6,"./run-page":10}],10:[function(require,module,exports){
 "use strict";
 
 const objectHtmlRenderer = require("./lib/object-html-renderer");
@@ -149,7 +508,7 @@ module.exports = function runPage(PageComponent) {
     objectHtmlRenderer.renderCycle();
 };
 
-},{"./lib/object-html-renderer":4,"./template/template":8}],7:[function(require,module,exports){
+},{"./lib/object-html-renderer":8,"./template/template":12}],11:[function(require,module,exports){
 "use strict";
 
 const { images_url } = require("../../../constants");
@@ -255,7 +614,7 @@ class NavBar {
 
 module.exports = NavBar;
 
-},{"../../../constants":2}],8:[function(require,module,exports){
+},{"../../../constants":2}],12:[function(require,module,exports){
 "use strict";
 
 const { images_url } = require("../../constants");
@@ -314,4 +673,4 @@ class Template {
 
 module.exports = Template;
 
-},{"../../constants":2,"./components/navbar":7}]},{},[5]);
+},{"../../constants":2,"./components/navbar":11}]},{},[9]);
diff --git a/public/software-development/software-development.js b/public/software-development/software-development.js
index ee207c5d599bb346460c0ed9a635105c306cad66..a3470c5597d37b553dee011dadbc611af708ce8b 100644
--- a/public/software-development/software-development.js
+++ b/public/software-development/software-development.js
@@ -18,6 +18,7 @@ const { server_url } = require("./config");
 
 module.exports = {
     images_url: `${server_url}/assets/images`,
+    articles_url: `${server_url}/articles`,
 };
 
 },{"./config":1}],3:[function(require,module,exports){
@@ -119,8 +120,9 @@ class SoftwareDevelopment {
             tag: "div",
             contents: [
                 {
-                    tag: "h1",
-                    contents: "Software",
+                    tag: "div",
+                    class: "page-header",
+                    contents: [{ tag: "h1", contents: "Software", class: "page-contents-center" }],
                 },
             ],
         };
diff --git a/public/style/homepage.css b/public/style/homepage.css
new file mode 100644
index 0000000000000000000000000000000000000000..b041bdd7d9be8a345ead083bf58b32285bd9d3f5
--- /dev/null
+++ b/public/style/homepage.css
@@ -0,0 +1,17 @@
+/* Error: Undefined variable.
+ *    ,
+ * 25 |                 color: $medium_grey;
+ *    |                        ^^^^^^^^^^^^
+ *    '
+ *   src/homepage.scss 25:24  root stylesheet */
+
+body::before {
+  font-family: "Source Code Pro", "SF Mono", Monaco, Inconsolata, "Fira Mono",
+      "Droid Sans Mono", monospace, monospace;
+  white-space: pre;
+  display: block;
+  padding: 1em;
+  margin-bottom: 1em;
+  border-bottom: 2px solid black;
+  content: "Error: Undefined variable.\a    \2577 \a 25 \2502                  color: $medium_grey;\a    \2502                         ^^^^^^^^^^^^\a    \2575 \a   src/homepage.scss 25:24  root stylesheet";
+}
diff --git a/public/style/pages/education/education.css b/public/style/pages/education/education.css
index 0ecb16805b4ea6b454bfcde825f6fa54cb580755..cb80c9db46a89bb99970832cf754384edb179aae 100644
--- a/public/style/pages/education/education.css
+++ b/public/style/pages/education/education.css
@@ -1,9 +1,9 @@
 /* Error: Undefined variable.
  *    ,
- * 17 |         color: $blue_3;
- *    |                ^^^^^^^
+ * 71 |                     border: solid $light_0;
+ *    |                                   ^^^^^^^^
  *    '
- *   src/pages/education/education.scss 17:16  root stylesheet */
+ *   src/pages/education/education.scss 71:35  root stylesheet */
 
 body::before {
   font-family: "Source Code Pro", "SF Mono", Monaco, Inconsolata, "Fira Mono",
@@ -13,5 +13,5 @@ body::before {
   padding: 1em;
   margin-bottom: 1em;
   border-bottom: 2px solid black;
-  content: "Error: Undefined variable.\a    \2577 \a 17 \2502          color: $blue_3;\a    \2502                 ^^^^^^^\a    \2575 \a   src/pages/education/education.scss 17:16  root stylesheet";
+  content: "Error: Undefined variable.\a    \2577 \a 71 \2502                      border: solid $light_0;\a    \2502                                    ^^^^^^^^\a    \2575 \a   src/pages/education/education.scss 71:35  root stylesheet";
 }
diff --git a/public/style/style.css b/public/style/style.css
index 8378af4d934198ff087680eec40e351d5253b063..bf2c45035d6809e52fa5b632222bb2bff9ab1e1f 100644
--- a/public/style/style.css
+++ b/public/style/style.css
@@ -21,6 +21,14 @@ body a:hover {
 body blue {
   color: #4baabb;
 }
+body .grid-3 {
+  display: grid;
+  grid-template-columns: 1fr 1fr 1fr;
+}
+body .bg-blue {
+  background-color: #4baabb;
+  color: #d4d9dd;
+}
 
 main {
   display: flex;
@@ -112,13 +120,14 @@ main header nav .burger {
   }
   main header nav .burger {
     display: flex;
+    justify-content: center;
+    align-items: center;
+    flex-direction: row;
+    flex-direction: column;
     font-weight: bold;
     border: 1px solid;
     margin: 0 20px;
     cursor: pointer;
-    flex-direction: column;
-    align-items: center;
-    justify-content: center;
     border-radius: 100%;
     width: 35px;
     height: 35px;
@@ -130,12 +139,12 @@ main header nav .burger {
   }
   main header nav ul.responsive-show {
     display: flex;
+    flex-direction: column;
     position: absolute;
     right: 0;
     max-width: 100vw;
     min-width: 50vw;
     top: 60px;
-    flex-direction: column;
     background-color: white;
     box-shadow: 0 4px 6px 2px #0000000a;
     height: unset;
@@ -166,24 +175,231 @@ main #page-container {
 }
 main #page-container .page-header {
   background-image: url("/assets/images/wallpaper_binary.png");
+  padding: 10px 0;
 }
-main #page-container #education-page h1 {
+main #page-container .page-header h1 {
   padding: 15px 40px 0;
   font-size: 25px;
+  color: #4baabb;
   margin: 0 auto;
-  max-width: 100%;
-  width: 1300px;
 }
-main #page-container #education-page h3.big {
-  font-size: 30px;
-}
-main #page-container #education-page .edu-philo {
-  padding: 15px 40px 15px 100px;
+main #page-container .page-header p {
+  color: #72e3f0;
   font-style: italic;
+  padding: 15px 40px 15px 100px;
+  margin: 0 auto;
+}
+main #page-container .page-header p * {
   color: #72e3f0;
+}
+@media screen and (max-width: 560px) {
+  main #page-container .page-header h1 {
+    padding: 15px 20px 0;
+  }
+  main #page-container .page-header p {
+    padding: 15px;
+  }
+}
+main #page-container .page-contents-center {
+  width: 1300px;
+  max-width: 100%;
   margin: 0 auto;
+}
+main #page-container #home-page {
+  display: flex;
+  flex-direction: column;
+  gap: 20px;
+  margin-bottom: 60px;
+}
+main #page-container #home-page .section-title {
+  padding: 10px;
+  margin: 0;
+}
+main #page-container #home-page .articles-displayer {
+  margin: 0 auto 40px;
+  display: grid;
+  grid-template-columns: 1fr auto 1fr;
+}
+main #page-container #home-page .articles-displayer .prev-btn,
+main #page-container #home-page .articles-displayer .next-btn {
+  border: none;
+  background-image: url("/assets/images/wallpaper_binary.png");
+  width: 50px;
+}
+main #page-container #home-page .articles-displayer .prev-btn.disabled,
+main #page-container #home-page .articles-displayer .next-btn.disabled {
+  pointer-events: none;
+}
+main #page-container #home-page .articles-displayer .prev-btn.active,
+main #page-container #home-page .articles-displayer .next-btn.active {
+  cursor: pointer;
+  color: #6b7880;
+}
+main #page-container #home-page .articles-displayer .prev-btn.active:hover,
+main #page-container #home-page .articles-displayer .next-btn.active:hover {
+  color: #d4d9dd;
+}
+main #page-container #home-page .articles-displayer .next-btn.active::before {
+  content: " ";
+  border-style: solid;
+  border-width: 4px 4px 0 0;
+  width: 20px;
+  height: 20px;
+  transform: rotate(45deg);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex-direction: row;
+  position: relative;
+}
+main #page-container #home-page .articles-displayer .prev-btn.active::before {
+  content: " ";
+  border-style: solid;
+  border-width: 4px 4px 0 0;
+  width: 20px;
+  height: 20px;
+  transform: rotate(-135deg);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex-direction: row;
+  position: relative;
+  left: 8px;
+}
+main #page-container #home-page .articles-displayer article {
+  display: grid;
+  gap: 5px 20px;
+  grid-template-columns: 1fr 1fr;
+  grid-template-rows: auto auto auto 1fr;
+  position: relative;
+  padding-left: 20px;
+}
+main #page-container #home-page .articles-displayer article .date {
+  grid-column: 1;
+  grid-row: 1;
+  text-align: right;
+}
+main #page-container #home-page .articles-displayer article .date span {
+  color: #6b7880;
+  font-style: italic;
+  font-size: 12px;
+}
+main #page-container #home-page .articles-displayer article .title {
+  grid-column: 1;
+  grid-row: 2;
+}
+main #page-container #home-page .articles-displayer article .title h3 {
+  margin: 0 0 10px;
+}
+main #page-container #home-page .articles-displayer article .subtitle {
+  grid-column: 1;
+  grid-row: 3;
+  font-style: italic;
+  font-size: 15px;
+}
+main #page-container #home-page .articles-displayer article .body {
+  grid-column: 1;
+  grid-row: 4;
+  min-height: 250px;
+  padding-bottom: 40px;
+}
+main #page-container #home-page .articles-displayer article .image-carousel {
+  grid-row: 1/span 4;
+  grid-column: 2;
+  overflow: hidden;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex-direction: row;
+  background-color: black;
+  position: relative;
+}
+main #page-container #home-page .articles-displayer article .image-carousel img {
+  position: absolute;
   max-width: 100%;
-  width: 1300px;
+  height: 400px;
+}
+main #page-container #home-page .articles-displayer article .image-carousel .carousel-bullets {
+  position: absolute;
+  bottom: 0;
+  padding: 20px;
+  display: flex;
+  gap: 10px;
+}
+main #page-container #home-page .articles-displayer article .image-carousel .carousel-bullets .bullet {
+  cursor: pointer;
+  width: 8px;
+  height: 8px;
+  background-color: #6b7880;
+  border-radius: 100%;
+  box-shadow: 0 0 3px black;
+}
+main #page-container #home-page .articles-displayer article .image-carousel .carousel-bullets .bullet.active {
+  background-color: #d4d9dd;
+}
+main #page-container #home-page .articles-displayer article.article-placeholder {
+  padding: 0 50px;
+}
+main #page-container #home-page .articles-displayer article.article-placeholder * {
+  background-color: #d4d9dd;
+}
+main #page-container #home-page .articles-displayer article.article-placeholder .date {
+  height: 10px;
+}
+main #page-container #home-page .articles-displayer article.article-placeholder .title {
+  height: 40px;
+}
+main #page-container #home-page .articles-displayer article.article-placeholder .subtitle {
+  height: 30px;
+}
+main #page-container #home-page .grid-3 {
+  gap: 30px;
+}
+main #page-container #home-page .grid-3 .theme-card {
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+  cursor: pointer;
+  transition: transform 0.3s;
+}
+main #page-container #home-page .grid-3 .theme-card .card-img {
+  width: 100%;
+  height: 240px;
+  overflow: hidden;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex-direction: row;
+  flex-direction: column;
+  background-image: url("/assets/images/wallpaper_binary.png");
+  position: relative;
+}
+main #page-container #home-page .grid-3 .theme-card .card-img img {
+  position: absolute;
+  min-width: 100%;
+  min-height: 100%;
+}
+main #page-container #home-page .grid-3 .theme-card .card-title h2 {
+  margin: 0;
+  text-align: center;
+  padding: 10px 20px;
+  color: #4baabb;
+}
+main #page-container #home-page .grid-3 .theme-card .card-description {
+  background-image: url("/assets/images/wallpaper_binary.png");
+  flex: 1;
+  padding: 20px 30px 30px;
+}
+main #page-container #home-page .grid-3 .theme-card .card-description p {
+  margin: 0;
+  color: #72e3f0;
+  text-align: center;
+}
+main #page-container #home-page .grid-3 .theme-card:hover {
+  transform: scale(1.03);
+}
+main #page-container #education-page h3.big {
+  font-size: 30px;
 }
 main #page-container #education-page .title-banner {
   display: flex;
@@ -209,13 +425,10 @@ main #page-container #education-page .title-banner h2 {
 }
 main #page-container #education-page .section-contents {
   padding: 20px 40px 60px;
-  margin: 0 auto;
   display: grid;
   grid-template-columns: auto 1fr;
   gap: 20px;
   height: auto;
-  width: 1300px;
-  max-width: 100%;
 }
 main #page-container #education-page .section-contents .full-row {
   grid-column: 1/span 2;
@@ -374,16 +587,9 @@ main #page-container #education-page .section-contents .infos-inscriptions .pric
   }
 }
 @media screen and (max-width: 560px) {
-  main #page-container #education-page h1 {
-    padding: 15px 20px 0;
-    font-size: 25px;
-  }
   main #page-container #education-page h3.big {
     font-size: 22px;
   }
-  main #page-container #education-page .edu-philo {
-    padding: 15px;
-  }
   main #page-container #education-page .title-banner {
     height: 170px;
     min-height: unset;
@@ -447,12 +653,14 @@ main #page-container #education-page .section-contents .infos-inscriptions .pric
   }
 }
 main footer {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex-direction: row;
+  flex-direction: column;
   width: 100%;
   background-image: url("/assets/images/wallpaper_binary.png");
   padding: 20px;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
   gap: 20px;
   font-size: 12px;
 }
@@ -463,6 +671,7 @@ main footer .logo {
   display: flex;
   justify-content: center;
   align-items: center;
+  flex-direction: row;
   gap: 10px;
 }
 main footer .logo img {
diff --git a/src/home-page-components/articles.js b/src/home-page-components/articles.js
new file mode 100644
index 0000000000000000000000000000000000000000..5aeae5ac09b54b235f538e91efb59f971d025dcc
--- /dev/null
+++ b/src/home-page-components/articles.js
@@ -0,0 +1,178 @@
+"use strict";
+
+const { articles_url } = require("../../constants");
+const { fetchjson, fetchtext } = require("../lib/fetch");
+const objectHtmlRenderer = require("../lib/object-html-renderer");
+const ImageCarousel = require("./image-carousel");
+
+class Articles {
+    constructor() {
+        this.id = performance.now().toString();
+        this.state = {
+            loading: true,
+            articles: [],
+            showArticleIndex: -1,
+        };
+        this.loadArticles();
+    }
+
+    loadArticles() {
+        fetchjson(`${articles_url}/index.json`)
+            .then(json => {
+                Promise.all(
+                    json.map(async articlePath => {
+                        const art = await fetchjson(`${articles_url}/${articlePath}`);
+                        const tmpSplit = articlePath.split("/");
+                        tmpSplit.pop();
+                        const absArtPath = `${articles_url}/${tmpSplit.join("/")}`;
+                        return Object.assign(art, { path: absArtPath });
+                    })
+                )
+                    .then(articles => this.setArticles(articles))
+                    .catch(e => console.log(e));
+            })
+            .catch(e => console.log(e));
+    }
+
+    async setArticles(articles) {
+        for (const article of articles) {
+            if (article.content_text.indexOf("<file>") !== -1) {
+                const txtPath = article.content_text.replace("<file>", "");
+                const txtValue = await fetchtext(`${article.path}/${txtPath}`);
+                article.content_text = txtValue;
+            }
+            article.date = new Date(article.date);
+        }
+        this.state.articles = articles.sort((a, b) => a.date - b.date);
+        this.state.showArticleIndex = this.state.articles.length - 1;
+        this.refresh();
+    }
+
+    refresh() {
+        objectHtmlRenderer.subRender(this.render(), document.getElementById(this.id), {
+            mode: "replace",
+        });
+    }
+
+    getArticleDate(date) {
+        return `${date.getDate()}-${date.getMonth() + 1}-${date.getFullYear()}`;
+    }
+
+    getArticleBody(text) {
+        return text
+            .split(" ")
+            .map(word => {
+                if (word.includes("http://") || word.includes("https://")) {
+                    const splitword = word.split("||");
+                    const href = splitword[0];
+                    const text = splitword.length > 1 ? splitword[1] : href;
+                    return `<a href=${href} target="_blank">${text}</a>`;
+                } else return word;
+            })
+            .join(" ")
+            .replaceAll("\n", "<br/>");
+    }
+
+    renderArticle(articleData) {
+        return {
+            tag: "article",
+            contents: [
+                {
+                    tag: "div",
+                    class: "date",
+                    contents: [{ tag: "span", contents: this.getArticleDate(articleData.date) }],
+                },
+                {
+                    tag: "div",
+                    class: "title",
+                    contents: [
+                        {
+                            tag: "h3",
+                            contents: articleData.title,
+                        },
+                    ],
+                },
+                {
+                    tag: "div",
+                    class: "subtitle",
+                    contents: [
+                        {
+                            tag: "strong",
+                            contents: articleData.subtitle,
+                        },
+                    ],
+                },
+                {
+                    tag: "div",
+                    class: "body",
+                    contents: [
+                        {
+                            tag: "p",
+                            contents: this.getArticleBody(articleData.content_text),
+                        },
+                    ],
+                },
+                new ImageCarousel({
+                    images: articleData.images.map(img => `${articleData.path}/images/${img}`),
+                }).render(),
+            ],
+        };
+    }
+
+    renderArticlePlaceholder() {
+        return {
+            tag: "article",
+            class: "article-placeholder page-contents-center",
+            contents: [
+                { tag: "div", class: "date" },
+                { tag: "div", class: "title" },
+                { tag: "div", class: "subtitle" },
+                { tag: "div", class: "body" },
+                { tag: "div", class: "image" },
+            ],
+        };
+    }
+
+    handleChangeArticle(dir) {
+        let { showArticleIndex, articles } = this.state;
+        showArticleIndex =
+            dir === "prev"
+                ? showArticleIndex - 1 >= 0
+                    ? showArticleIndex - 1
+                    : 0
+                : showArticleIndex + 1 <= articles.length - 1
+                ? showArticleIndex + 1
+                : articles.length - 1;
+        this.state.showArticleIndex = showArticleIndex;
+        this.refresh();
+    }
+
+    render() {
+        const { articles, showArticleIndex } = this.state,
+            showNext = showArticleIndex < articles.length - 1,
+            showPrev = showArticleIndex > 0;
+        return {
+            tag: "div",
+            id: this.id,
+            class: "articles-displayer page-contents-center",
+            contents:
+                articles.length > 0
+                    ? [
+                          {
+                              tag: "button",
+                              class: `prev-btn ${!showPrev ? "disabled" : "active"}`,
+                              onclick: this.handleChangeArticle.bind(this, "prev"),
+                          },
+                          this.renderArticle(articles[showArticleIndex]),
+                          {
+                              tag: "button",
+                              class: `next-btn ${!showNext ? "disabled" : "active"}`,
+                              onclick: this.handleChangeArticle.bind(this, "next"),
+                          },
+                      ]
+                    : [this.renderArticlePlaceholder()],
+        };
+    }
+}
+
+module.exports = Articles;
diff --git a/src/home-page-components/image-carousel.js b/src/home-page-components/image-carousel.js
new file mode 100644
index 0000000000000000000000000000000000000000..f32b41c70bc4a0471442a493806df662eb2b69b3
--- /dev/null
+++ b/src/home-page-components/image-carousel.js
@@ -0,0 +1,63 @@
+"use strict";
+
+const objectHtmlRenderer = require("../lib/object-html-renderer");
+
+class ImageCarousel {
+    constructor(props) {
+        this.props = props;
+        this.id = performance.now();
+        this.state = {
+            showImageIndex: 0,
+        };
+        this.RUN_INTERVAL = 5000;
+        this.run();
+    }
+
+    run() {
+        this.runningInterval = setInterval(() => {
+            let { showImageIndex } = this.state;
+            const { images } = this.props;
+            this.state.showImageIndex = showImageIndex < images.length - 1 ? ++showImageIndex : 0;
+            this.refreshImage();
+        }, this.RUN_INTERVAL);
+    }
+
+    setImageIndex(i) {
+        clearInterval(this.runningInterval);
+        this.state.showImageIndex = i;
+        this.refreshImage();
+    }
+
+    refreshImage() {
+        objectHtmlRenderer.subRender(this.render(), document.getElementById(this.id), {
+            mode: "replace",
+        });
+    }
+
+    render() {
+        const { showImageIndex } = this.state;
+        const { images } = this.props;
+        return {
+            tag: "div",
+            id: this.id,
+            class: "image-carousel",
+            contents: [
+                { tag: "img", src: images[showImageIndex] },
+                {
+                    tag: "div",
+                    class: "carousel-bullets",
+                    contents: images.map((_, i) => {
+                        const active = showImageIndex === i;
+                        return {
+                            tag: "span",
+                            class: `bullet ${active ? "active" : ""}`,
+                            onclick: this.setImageIndex.bind(this, i),
+                        };
+                    }),
+                },
+            ],
+        };
+    }
+}
+
+module.exports = ImageCarousel;
diff --git a/src/home-page-components/theme-card.js b/src/home-page-components/theme-card.js
new file mode 100644
index 0000000000000000000000000000000000000000..a6044da001a9889ae28a0e8d6318458a54e63776
--- /dev/null
+++ b/src/home-page-components/theme-card.js
@@ -0,0 +1,36 @@
+"use strict";
+
+const { images_url } = require("../../constants");
+
+class ThemeCard {
+    constructor(props) {
+        this.props = props;
+    }
+
+    render() {
+        return {
+            tag: "a",
+            class: "theme-card",
+            href: this.props.href,
+            contents: [
+                {
+                    tag: "div",
+                    class: "card-img",
+                    contents: [{ tag: "img", src: `${images_url}/${this.props.img}` }],
+                },
+                {
+                    tag: "div",
+                    class: "card-title",
+                    contents: [{ tag: "h2", class: "section-title", contents: this.props.title }],
+                },
+                {
+                    tag: "div",
+                    class: "card-description",
+                    contents: [{ tag: "p", contents: this.props.description }],
+                },
+            ],
+        };
+    }
+}
+
+module.exports = ThemeCard;
diff --git a/src/homepage.js b/src/homepage.js
index 77948a24efa7d2619862652a1fcb57f0d5ad043f..a7b183010d17afcf5cfb51bfc9be57c9120646df 100644
--- a/src/homepage.js
+++ b/src/homepage.js
@@ -1,5 +1,8 @@
 "use strict";
 
+const Articles = require("./home-page-components/articles");
+const ThemeCard = require("./home-page-components/theme-card");
+
 class HomePage {
     constructor(args) {
         Object.assign(this, args);
@@ -8,10 +11,57 @@ class HomePage {
     render() {
         return {
             tag: "div",
+            id: "home-page",
             contents: [
                 {
-                    tag: "h1",
-                    contents: "Kuadrado Software",
+                    tag: "div",
+                    class: "page-header",
+                    contents: [
+                        { tag: "h1", contents: "Kuadrado Software", class: "page-contents-center" },
+                        {
+                            tag: "p",
+                            class: "page-contents-center",
+                            contents: `<b>Kvadrata rado</b> veut dire "roue carrée" en Esperanto, c'est le symbole que nous avons choisi pour Kuadrado 
+                            pour dire qu'on aime bien fabriquer les trucs nous même, avec des briques aussi élémentaires que possible, 
+                            pour le plaisir de les maîtriser et de les comprendre. Quitte parfois à réinventer un peu la roue.
+                            `,
+                        },
+                    ],
+                },
+                {
+                    tag: "section",
+                    class: "page-contents-center",
+                    contents: [
+                        { tag: "h2", contents: "Actu", class: "section-title bg-blue" },
+                        new Articles().render(),
+                    ],
+                },
+                {
+                    tag: "section",
+                    class: "page-contents-center grid-3",
+                    contents: [
+                        {
+                            title: "Jeux",
+                            img: "screen_fantom_quest.jpg",
+                            href: "/games/",
+                            description:
+                                "Toutes nos créations vidéoludiques, jeux web et jeux PC, projets en cours, c'est par ici que ça se passe.",
+                        },
+                        {
+                            title: "Software",
+                            img: "learning_theme_coding.png",
+                            href: "/software-development/",
+                            description:
+                                "Des fois quand on a besoin d'un outil, on le fabrique nous même (si ça nous amuse) ! Retrouvez les projets en détail.",
+                        },
+                        {
+                            title: "Pédagogie",
+                            img: "popularization_banner.png",
+                            href: "/education/",
+                            description:
+                                "La pédagogie est une arme puissante pour faire tomber les barrières entre les gens et la technologie, et nous sommes bien décidés à en faire usage !",
+                        },
+                    ].map(cardProps => new ThemeCard(cardProps).render()),
                 },
             ],
         };
diff --git a/src/homepage.scss b/src/homepage.scss
new file mode 100644
index 0000000000000000000000000000000000000000..d4cbf67fd3311570702cbdc469b40c72453c25cd
--- /dev/null
+++ b/src/homepage.scss
@@ -0,0 +1,189 @@
+#home-page {
+    display: flex;
+    flex-direction: column;
+    gap: 20px;
+    margin-bottom: 60px;
+    .section-title {
+        padding: 10px;
+        margin: 0;
+    }
+
+    .articles-displayer {
+        margin: 0 auto 40px;
+        display: grid;
+        grid-template-columns: 1fr auto 1fr;
+        .prev-btn,
+        .next-btn {
+            border: none;
+            background-image: url("/assets/images/wallpaper_binary.png");
+            width: 50px;
+            &.disabled {
+                pointer-events: none;
+            }
+            &.active {
+                cursor: pointer;
+                color: $medium_grey;
+                &:hover {
+                    color: $light_0;
+                }
+            }
+        }
+        .next-btn {
+            &.active {
+                &::before {
+                    content: " ";
+                    border-style: solid;
+                    border-width: 4px 4px 0 0;
+                    width: 20px;
+                    height: 20px;
+                    transform: rotate(45deg);
+                    @include flex-center;
+                    position: relative;
+                }
+            }
+        }
+        .prev-btn {
+            &.active {
+                &::before {
+                    content: " ";
+                    border-style: solid;
+                    border-width: 4px 4px 0 0;
+                    width: 20px;
+                    height: 20px;
+                    transform: rotate(-135deg);
+                    @include flex-center;
+                    position: relative;
+                    left: 8px;
+                }
+            }
+        }
+        article {
+            display: grid;
+            gap: 5px 20px;
+            grid-template-columns: 1fr 1fr;
+            grid-template-rows: auto auto auto 1fr;
+            position: relative;
+            padding-left: 20px;
+            .date {
+                grid-column: 1;
+                grid-row: 1;
+                text-align: right;
+                span {
+                    color: $medium_grey;
+                    font-style: italic;
+                    font-size: 12px;
+                }
+            }
+            .title {
+                grid-column: 1;
+                grid-row: 2;
+                h3 {
+                    margin: 0 0 10px;
+                }
+            }
+            .subtitle {
+                grid-column: 1;
+                grid-row: 3;
+                font-style: italic;
+                font-size: 15px;
+            }
+            .body {
+                grid-column: 1;
+                grid-row: 4;
+                min-height: 250px;
+                padding-bottom: 40px;
+            }
+            .image-carousel {
+                grid-row: 1 / span 4;
+                grid-column: 2;
+                overflow: hidden;
+                @include flex-center;
+                background-color: black;
+                position: relative;
+                img {
+                    position: absolute;
+                    max-width: 100%;
+                    height: 400px;
+                }
+                .carousel-bullets {
+                    position: absolute;
+                    bottom: 0;
+                    padding: 20px;
+                    display: flex;
+                    gap: 10px;
+                    .bullet {
+                        cursor: pointer;
+                        width: 8px;
+                        height: 8px;
+                        background-color: $medium_grey;
+                        border-radius: 100%;
+                        box-shadow: 0 0 3px black;
+                        &.active {
+                            background-color: $light_0;
+                        }
+                    }
+                }
+            }
+            &.article-placeholder {
+                padding: 0 50px;
+                * {
+                    background-color: $light_0;
+                }
+                .date {
+                    height: 10px;
+                }
+                .title {
+                    height: 40px;
+                }
+                .subtitle {
+                    height: 30px;
+                }
+            }
+        }
+    }
+
+    .grid-3 {
+        gap: 30px;
+        .theme-card {
+            display: flex;
+            flex-direction: column;
+            width: 100%;
+            cursor: pointer;
+            .card-img {
+                width: 100%;
+                height: 240px;
+                overflow: hidden;
+                @include flex-center-col;
+                background-image: url("/assets/images/wallpaper_binary.png");
+                position: relative;
+                img {
+                    position: absolute;
+                    min-width: 100%;
+                    min-height: 100%;
+                }
+            }
+            .card-title {
+                h2 {
+                    margin: 0;
+                    text-align: center;
+                    padding: 10px 20px;
+                    color: $blue_2;
+                }
+            }
+            .card-description {
+                background-image: url("/assets/images/wallpaper_binary.png");
+                flex: 1;
+                padding: 20px 30px 30px;
+                p {
+                    margin: 0;
+                    color: $blue_3;
+                    text-align: center;
+                }
+            }
+            transition: transform 0.3s;
+            &:hover {
+                transform: scale(1.03);
+            }
+        }
+    }
+}
diff --git a/src/lib/fetch.js b/src/lib/fetch.js
new file mode 100644
index 0000000000000000000000000000000000000000..bb47973f8b3905f1330ffd75b33546b7262d01d1
--- /dev/null
+++ b/src/lib/fetch.js
@@ -0,0 +1,23 @@
+"use strict";
+
+function fetchjson(url) {
+    return new Promise((resolve, reject) => {
+        fetch(url)
+            .then(r => r.json())
+            .then(r => resolve(r))
+            .catch(e => reject(e));
+    });
+};
+
+function fetchtext(url) {
+    return new Promise((resolve, reject) => {
+        fetch(url)
+            .then(r => r.text())
+            .then(r => resolve(r))
+            .catch(e => reject(e));
+    });
+};
+
+module.exports = {
+    fetchjson, fetchtext
+}
diff --git a/src/pages/education/components/game-studio-club.js b/src/pages/education/components/game-studio-club.js
index 0d0681a3d7fdf278b8561a8a1f3e76af24062225..0324653c29c9527fc5567b02b4898e30e567899b 100644
--- a/src/pages/education/components/game-studio-club.js
+++ b/src/pages/education/components/game-studio-club.js
@@ -90,7 +90,7 @@ class GameStudioClub {
                 },
                 {
                     tag: "div",
-                    class: "section-contents",
+                    class: "section-contents page-contents-center",
                     contents: [
                         {
                             tag: "div",
diff --git a/src/pages/education/components/popularization.js b/src/pages/education/components/popularization.js
index 64b954c5b04a77bdc50b33addd1ce36c56ac786f..73c37363c48823a28da80312dd234db41d5399d6 100644
--- a/src/pages/education/components/popularization.js
+++ b/src/pages/education/components/popularization.js
@@ -55,7 +55,7 @@ class Popularization {
                 },
                 {
                     tag: "div",
-                    class: "section-contents",
+                    class: "section-contents page-contents-center",
                     contents: [
                         {
                             tag: "div",
diff --git a/src/pages/education/education.js b/src/pages/education/education.js
index 451a28e1bfef6ef120ca43cf7c1bf6a3362f551f..03ca494e1c4ea140c677b543ab11cb8046b840c1 100644
--- a/src/pages/education/education.js
+++ b/src/pages/education/education.js
@@ -17,10 +17,10 @@ class EducationPage {
                     tag: "div",
                     class: "page-header",
                     contents: [
-                        { tag: "h1", contents: "<blue>Pédagogie</blue>" },
+                        { tag: "h1", contents: "Pédagogie", class: "page-contents-center" },
                         {
                             tag: "p",
-                            class: "edu-philo",
+                            class: "page-contents-center",
                             contents:
                                 "Démystifier et s'approprier la technologie par le partage de connaissances.",
                         },
diff --git a/src/pages/education/education.scss b/src/pages/education/education.scss
index 8be252e185ca59842f2147b0b3c4b75e7a947b63..61552c980817d35fb8b8e3ddd715677356a2d1e0 100644
--- a/src/pages/education/education.scss
+++ b/src/pages/education/education.scss
@@ -1,24 +1,9 @@
 #education-page {
-    h1 {
-        padding: 15px 40px 0;
-        font-size: 25px;
-        margin: 0 auto;
-        max-width: 100%;
-        width: 1300px;
-    }
     h3 {
         &.big {
             font-size: 30px;
         }
     }
-    .edu-philo {
-        padding: 15px 40px 15px 100px;
-        font-style: italic;
-        color: $blue_3;
-        margin: 0 auto;
-        max-width: 100%;
-        width: 1300px;
-    }
     .title-banner {
         display: flex;
         justify-content: flex-end;
@@ -43,13 +28,10 @@
     }
     .section-contents {
         padding: 20px 40px 60px;
-        margin: 0 auto;
         display: grid;
         grid-template-columns: auto 1fr;
         gap: 20px;
         height: auto;
-        width:1300px;
-        max-width: 100%;
         .full-row {
             grid-column: 1 / span 2;
         }
@@ -217,18 +199,11 @@
     }
 
     @media screen and (max-width: $screen_s) {
-        h1 {
-            padding: 15px 20px 0;
-            font-size: 25px;
-        }
         h3 {
             &.big {
                 font-size: 22px;
             }
         }
-        .edu-philo {
-            padding: 15px;
-        }
         .title-banner {
             height: 170px;
             min-height: unset;
diff --git a/src/pages/games/games.js b/src/pages/games/games.js
index 3583a6f950bd055dce16a872bb84c8f56e7b4d24..c39b9d68572130f79b4d59860bc8d80fc0bf49fc 100644
--- a/src/pages/games/games.js
+++ b/src/pages/games/games.js
@@ -10,8 +10,11 @@ class GamesPage {
             tag: "div",
             contents: [
                 {
-                    tag: "h1",
-                    contents: "Games",
+                    tag: "div",
+                    class: "page-header",
+                    contents: [
+                        { tag: "h1", contents: "Jeux", class: "page-contents-center" }
+                    ],
                 },
             ],
         };
diff --git a/src/pages/software-development/software-development.js b/src/pages/software-development/software-development.js
index e85932cf9e1ae00ba29c4dc8321f462cc4093aea..f3c9bfb7ca2b072a78bd1e734ab96e59a106f43d 100644
--- a/src/pages/software-development/software-development.js
+++ b/src/pages/software-development/software-development.js
@@ -10,8 +10,9 @@ class SoftwareDevelopment {
             tag: "div",
             contents: [
                 {
-                    tag: "h1",
-                    contents: "Software",
+                    tag: "div",
+                    class: "page-header",
+                    contents: [{ tag: "h1", contents: "Software", class: "page-contents-center" }],
                 },
             ],
         };
diff --git a/src/style.scss b/src/style.scss
index b98f6e35a3588b66d2cb1a20402ba993400fb03a..b9cb669491048f5a5c712b605c274e22aca07c31 100644
--- a/src/style.scss
+++ b/src/style.scss
@@ -23,10 +23,19 @@ body {
     blue {
         color: $blue_2;
     }
+
+    .grid-3 {
+        display: grid;
+        grid-template-columns: 1fr 1fr 1fr;
+    }
+
+    .bg-blue {
+        background-color: $blue_2;
+        color: $light_0;
+    }
 }
 
 main {
-    // background: url("/assets/images/wallpaper_binary_white.png");
     display: flex;
     flex-direction: column;
     align-items: center;
@@ -120,14 +129,11 @@ main {
             @media screen and (max-width: $screen_s) {
                 justify-content: space-between;
                 .burger {
-                    display: flex;
+                    @include flex-center-col;
                     font-weight: bold;
                     border: 1px solid;
                     margin: 0 20px;
                     cursor: pointer;
-                    flex-direction: column;
-                    align-items: center;
-                    justify-content: center;
                     border-radius: 100%;
                     width: 35px;
                     height: 35px;
@@ -138,12 +144,12 @@ main {
                     display: none;
                     &.responsive-show {
                         display: flex;
+                        flex-direction: column;
                         position: absolute;
                         right: 0;
                         max-width: 100vw;
                         min-width: 50vw;
                         top: $navbar_height;
-                        flex-direction: column;
                         background-color: white;
                         box-shadow: 0 4px 6px 2px #0000000a;
                         height: unset;
@@ -181,26 +187,26 @@ main {
         width: 100%;
         flex: 1;
         .page-header {
-            background-image: url("/assets/images/wallpaper_binary.png");
+            @include page-header;
+        }
+        .page-contents-center {
+            @include page-contents-center;
         }
+        @import "./homepage.scss";
         @import "./pages/education/education.scss";
     }
     footer {
+        @include flex-center-col;
         width: 100%;
         background-image: url("/assets/images/wallpaper_binary.png");
         padding: 20px;
-        display: flex;
-        flex-direction: column;
-        align-items: center;
         gap: 20px;
         font-size: 12px;
         span {
             color: $light_1;
         }
         .logo {
-            display: flex;
-            justify-content: center;
-            align-items: center;
+            @include flex-center;
             gap: 10px;
             img {
                 width: 35px;
diff --git a/src/theme.scss b/src/theme.scss
index 8bd15bc955adb6c4120dc7a424a359c0e056b335..e7ae8e2f43eb36d7f81e5b80c66e2d8bc265d445 100644
--- a/src/theme.scss
+++ b/src/theme.scss
@@ -25,3 +25,51 @@ $screen_xs: 480px;
 
 // constants
 $navbar_height: 60px;
+$page_contents_center_width: 1300px;
+
+// mixins
+@mixin page-contents-center {
+    width: $page_contents_center_width;
+    max-width: 100%;
+    margin: 0 auto;
+}
+
+@mixin page-header {
+    background-image: url("/assets/images/wallpaper_binary.png");
+    padding: 10px 0;
+    h1 {
+        padding: 15px 40px 0;
+        font-size: 25px;
+        color: $blue_2;
+        margin: 0 auto;
+    }
+    p {
+        color: $blue_3;
+        * {
+            color: $blue_3;
+        }
+        font-style: italic;
+        padding: 15px 40px 15px 100px;
+        margin: 0 auto;
+    }
+    @media screen and (max-width: $screen_s) {
+        h1 {
+            padding: 15px 20px 0;
+        }
+        p {
+            padding: 15px;
+        }
+    }
+}
+
+@mixin flex-center {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    flex-direction: row;
+}
+
+@mixin flex-center-col {
+    @include flex-center;
+    flex-direction: column;
+}