diff --git a/build.js b/build.js
index 8fb487fc2392357576964b995c29b65b9cc293e7..616d21b8e3810200e7f02cf40f077146dc598f8b 100644
--- a/build.js
+++ b/build.js
@@ -3,7 +3,7 @@
 "use strict";
 
 const build_conf = {
-    protected_dirs: ["assets", "style", "articles"],
+    protected_dirs: ["assets", "style", "news-articles", "game-articles", "software-articles"],
 };
 
 const fs = require("fs");
diff --git a/config.js b/config.js
index bdaf34374091a05af107cca712d3c890055c7e51..2f677c61bc76a98d868dd805a3ee69803d66d649 100644
--- a/config.js
+++ b/config.js
@@ -10,4 +10,4 @@ switch (ENV) {
         server_url = "http://kuadrado-software.fr";
 }
 
-module.exports = { server_url };
+module.exports = { server_url, in_construction: true };
diff --git a/constants.js b/constants.js
index fd8b9bd8a32e15fd08a8612c718d299b3241bf27..50ac463a0fe060ae6a0b7e8785835b0f58480e95 100644
--- a/constants.js
+++ b/constants.js
@@ -2,5 +2,7 @@ const { server_url } = require("./config");
 
 module.exports = {
     images_url: `${server_url}/assets/images`,
-    articles_url: `${server_url}/articles`,
+    news_articles_url: `${server_url}/news-articles`,
+    game_articles_url: `${server_url}/game-articles`,
+    software_articles_url: `${server_url}/software-articles`,
 };
diff --git a/nginx.conf b/nginx.conf
index 266e0bfff1acea1139655dc0e38a34e0415eb9ec..f9dfe32359e324b3ba1160364bd91575072a781c 100644
--- a/nginx.conf
+++ b/nginx.conf
@@ -28,8 +28,12 @@ http {
 	
     include /etc/nginx/conf.d/*.conf;
 
-	# server {
-    #     add_header 'Access-Control-Allow-Origin' '*';
-	# }
+	server {
+        server_name kuadrado-software.fr www.kuadrado-software.fr;
+        location / {
+            add_header Access-Control-Allow-Origin *;
+        }
+    }
+
 }
 
diff --git a/public/assets/images/wallpaper_warning.svg b/public/assets/images/wallpaper_warning.svg
new file mode 100644
index 0000000000000000000000000000000000000000..ab639d4cf8f9d60e423555f67dced45e5442f6c9
--- /dev/null
+++ b/public/assets/images/wallpaper_warning.svg
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="79.375mm"
+   height="79.375mm"
+   viewBox="0 0 79.375 79.375"
+   version="1.1"
+   id="svg8"
+   inkscape:version="1.0.1 (0767f8302a, 2020-10-17)"
+   sodipodi:docname="wallpaper_warning.svg">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.8284271"
+     inkscape:cx="166.22215"
+     inkscape:cy="210.50122"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     inkscape:document-rotation="0"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="1920"
+     inkscape:window-height="966"
+     inkscape:window-x="1920"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-68.684253,-89.92156)">
+    <g
+       id="g847"
+       transform="translate(22.712161,-53.33137)">
+      <path
+         style="fill:#fece00;stroke-width:0.264583"
+         d="m 125.34553,143.25255 c 3.9e-4,-2e-5 0.002,39.63184 0.002,39.63184 l -39.636437,39.74407 -39.737207,-0.0117 c 26.12056,-26.62352 52.901255,-52.96121 79.371964,-79.36422 z m -79.373459,3.8e-4 39.742018,0 c 0,0 -39.533678,39.4967 -39.743925,39.4967 z"
+         id="path851"
+         sodipodi:nodetypes="cccccccccc" />
+      <path
+         style="fill:#d79400;stroke-width:0.264583"
+         d="m 45.970159,182.74963 39.743932,-39.4967 39.631439,-3.8e-4 c 0,0 -52.907028,53.09226 -79.371964,79.36422 z m 39.740934,39.87883 39.636437,-39.74407 -3.9e-4,39.74354 z"
+         id="path849"
+         sodipodi:nodetypes="ccccccccc" />
+    </g>
+  </g>
+</svg>
diff --git a/public/education/education.js b/public/education/education.js
index 75582984892951582798ccff04f88e0a44ffb995..7000373e2c802703d2df725f2a96e5b26d1830a9 100644
--- a/public/education/education.js
+++ b/public/education/education.js
@@ -11,14 +11,16 @@ switch (ENV) {
         server_url = "http://kuadrado-software.fr";
 }
 
-module.exports = { server_url };
+module.exports = { server_url, in_construction: true };
 
 },{}],2:[function(require,module,exports){
 const { server_url } = require("./config");
 
 module.exports = {
     images_url: `${server_url}/assets/images`,
-    articles_url: `${server_url}/articles`,
+    news_articles_url: `${server_url}/news-articles`,
+    game_articles_url: `${server_url}/game-articles`,
+    software_articles_url: `${server_url}/software-articles`,
 };
 
 },{"./config":1}],3:[function(require,module,exports){
@@ -828,6 +830,7 @@ module.exports = NavBar;
 },{"../../../constants":2}],10:[function(require,module,exports){
 "use strict";
 
+const { in_construction } = require("../../config");
 const { images_url } = require("../../constants");
 const NavBar = require("./components/navbar");
 
@@ -843,8 +846,19 @@ class Template {
                     tag: "header",
                     contents: [new NavBar().render()],
                 },
+                in_construction && {
+                    tag: "section",
+                    class: "warning-banner",
+                    contents: [
+                        {
+                            tag: "strong",
+                            class: "page-contents-center",
+                            contents: "Site en construction ...",
+                        },
+                    ],
+                },
                 {
-                    tag: "div",
+                    tag: "section",
                     id: "page-container",
                     contents: [this.props.page.render()],
                 },
@@ -861,14 +875,15 @@ class Template {
                                 },
                                 {
                                     tag: "img",
-                                    class:"text-logo",
+                                    class: "text-logo",
                                     src: `${images_url}/logo_kuadrado_txt.svg`,
                                 },
                             ],
                         },
                         {
-                            tag:"span",
-                            contents: "Toutes les images du site ont été réalisées par nos soins et peuvent être réutilisées pour un usage personnel."
+                            tag: "span",
+                            contents:
+                                "Toutes les images du site ont été réalisées par nos soins et peuvent être réutilisées pour un usage personnel.",
                         },
                         {
                             tag: "a",
@@ -884,4 +899,4 @@ class Template {
 
 module.exports = Template;
 
-},{"../../constants":2,"./components/navbar":9}]},{},[7]);
+},{"../../config":1,"../../constants":2,"./components/navbar":9}]},{},[7]);
diff --git a/public/game-articles/fantom_quest/fantom_quest.json b/public/game-articles/fantom_quest/fantom_quest.json
new file mode 100644
index 0000000000000000000000000000000000000000..62c6e4a4721414a9b5f139c8c6e623847d42c990
--- /dev/null
+++ b/public/game-articles/fantom_quest/fantom_quest.json
@@ -0,0 +1,27 @@
+{
+    "title": "Fantom Quest",
+    "subtitle": "Le labyrinthe de la quête d'identité",
+    "tags": ["jeu web", "pixelart", "javascript", "labyrinthe"],
+    "body": "<file>fantom_quest.txt",
+    "images": [
+        "screen_fantom_quest_1.jpg",
+        "screen_fantom_quest_2.jpg",
+        "screen_fantom_quest_3.jpg",
+        "screen_fantom_quest_4.jpg",
+        "screen_fantom_quest_5.jpg"
+    ],
+    "team_subarticles": [
+        {
+            "title": "Lucie Ventadour",
+            "subtitle": "Artiste 2D, illustratice, artiste peintre",
+            "body": "<file>lucie_ventadour.txt",
+            "images": ["lucipix.png"]
+        },
+        {
+            "title": "Pierre Jarriges",
+            "subtitle": "Auteur BD, dessinateur, compositeur, développeur.",
+            "body": "<file>pijar.txt",
+            "images": ["pijarpix.png"]
+        }
+    ]
+}
diff --git a/public/game-articles/fantom_quest/fantom_quest.txt b/public/game-articles/fantom_quest/fantom_quest.txt
new file mode 100644
index 0000000000000000000000000000000000000000..86e588e6928d1a42f24f714ac4830f2f04436f71
--- /dev/null
+++ b/public/game-articles/fantom_quest/fantom_quest.txt
@@ -0,0 +1,9 @@
+Un petit fantôme en quête d'identité va devoir gravir chaque étage d'un donjon afin de rencontrer la sorcière qui lui révélera sa vraie nature.
+
+Ce petit jeu de quête minimaliste en forme de labyrinthe sera jouable directement sur navigateur ou à télécharger sur pc.
+Sortie prévue : Mars 2021 (si on y arrive !)
+
+Concept original et graphismes : Lucie Ventadour ( http://lucipix.canalblog.com/||site_web ).
+Programmation Javascript et bande son: Pierre Jarriges
+
+https://lab.frogg.it/peter_rabbit/fantom-quest||Dépôt_du_code_source 
diff --git a/public/game-articles/fantom_quest/images/lucipix.png b/public/game-articles/fantom_quest/images/lucipix.png
new file mode 100644
index 0000000000000000000000000000000000000000..f2016e3cb8a2879daf03a15bbcb9eca16a944cab
Binary files /dev/null and b/public/game-articles/fantom_quest/images/lucipix.png differ
diff --git a/public/game-articles/fantom_quest/images/pijarpix.png b/public/game-articles/fantom_quest/images/pijarpix.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd32b420ec5b3361fb522bab67fab21dfc8241e1
Binary files /dev/null and b/public/game-articles/fantom_quest/images/pijarpix.png differ
diff --git a/public/game-articles/fantom_quest/images/screen_fantom_quest_1.jpg b/public/game-articles/fantom_quest/images/screen_fantom_quest_1.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..733ebe66d706739b8968e2ea9cf39b55edb300d8
Binary files /dev/null and b/public/game-articles/fantom_quest/images/screen_fantom_quest_1.jpg differ
diff --git a/public/game-articles/fantom_quest/images/screen_fantom_quest_2.jpg b/public/game-articles/fantom_quest/images/screen_fantom_quest_2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..419a54956086d4bf932e1a1fc7bb30310f4151c0
Binary files /dev/null and b/public/game-articles/fantom_quest/images/screen_fantom_quest_2.jpg differ
diff --git a/public/game-articles/fantom_quest/images/screen_fantom_quest_3.jpg b/public/game-articles/fantom_quest/images/screen_fantom_quest_3.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..b76c04a8cc1c05ef5e96cf2c94d525b1a17b0a27
Binary files /dev/null and b/public/game-articles/fantom_quest/images/screen_fantom_quest_3.jpg differ
diff --git a/public/game-articles/fantom_quest/images/screen_fantom_quest_4.jpg b/public/game-articles/fantom_quest/images/screen_fantom_quest_4.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..1f2ab664d3e99f3fab911879e70c7bd37b8cac57
Binary files /dev/null and b/public/game-articles/fantom_quest/images/screen_fantom_quest_4.jpg differ
diff --git a/public/game-articles/fantom_quest/images/screen_fantom_quest_5.jpg b/public/game-articles/fantom_quest/images/screen_fantom_quest_5.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..57a6e6ba3f07aa7bdff4695ec7c159524eb6f366
Binary files /dev/null and b/public/game-articles/fantom_quest/images/screen_fantom_quest_5.jpg differ
diff --git a/public/game-articles/fantom_quest/lucie_ventadour.txt b/public/game-articles/fantom_quest/lucie_ventadour.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9c20aae109ac7292c035a6bb0d997576e7d0f32d
--- /dev/null
+++ b/public/game-articles/fantom_quest/lucie_ventadour.txt
@@ -0,0 +1,2 @@
+Salut moi c'est lucette, je suis une geek et je vois la vie en pixels >< et ouais.
+https://www.lucieventadour.com/||Mon_site  |  http://lucipix.canalblog.com/||Mon_blog_pix
\ No newline at end of file
diff --git a/public/game-articles/fantom_quest/pijar.txt b/public/game-articles/fantom_quest/pijar.txt
new file mode 100644
index 0000000000000000000000000000000000000000..afc7e86ad39df6cdcd2141cf1936c69877a5bcb6
--- /dev/null
+++ b/public/game-articles/fantom_quest/pijar.txt
@@ -0,0 +1,4 @@
+Salut moi c'est pijar. Je fais des trucs.
+
+J'aime bien le code.
+Et je fais du dessin et tout.
\ No newline at end of file
diff --git a/public/game-articles/index.json b/public/game-articles/index.json
new file mode 100644
index 0000000000000000000000000000000000000000..b6bc394a7c546e147834a8f29597b6f62428c3a5
--- /dev/null
+++ b/public/game-articles/index.json
@@ -0,0 +1 @@
+["fantom_quest/fantom_quest.json"]
diff --git a/public/games/games.js b/public/games/games.js
index 64c83346ffc44445a68d9cd9e27dfabdac2b3233..97d9444dd8c79ed23d48b6902225d424bd12519c 100644
--- a/public/games/games.js
+++ b/public/games/games.js
@@ -11,19 +11,184 @@ switch (ENV) {
         server_url = "http://kuadrado-software.fr";
 }
 
-module.exports = { server_url };
+module.exports = { server_url, in_construction: true };
 
 },{}],2:[function(require,module,exports){
 const { server_url } = require("./config");
 
 module.exports = {
     images_url: `${server_url}/assets/images`,
-    articles_url: `${server_url}/articles`,
+    news_articles_url: `${server_url}/news-articles`,
+    game_articles_url: `${server_url}/game-articles`,
+    software_articles_url: `${server_url}/software-articles`,
 };
 
 },{"./config":1}],3:[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] },
+                images.length > 1 && {
+                    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":6}],4:[function(require,module,exports){
+"use strict";
+
+const { fetchjson, fetchtext } = require("./fetch");
+
+function getArticleBody(text) {
+    return text
+        .split(" ")
+        .map(word => {
+            if (word.includes("http://") || word.includes("https://")) {
+                const splitword = word.split("||");
+                const href = splitword[0].match(/http.+/);
+                const text = splitword.length > 1 ? splitword[1].replaceAll("_", " ") : href;
+                return word.replace(/http.*/, `<a href=${href} target="_blank">${text}</a>`);
+            } else return word;
+        })
+        .join(" ")
+        .replaceAll("\n", "<br/>");
+}
+
+function getArticleDate(date) {
+    return `${date.getDate()}-${date.getMonth() + 1}-${date.getFullYear()}`;
+}
+
+function loadArticles(dir_url) {
+    return new Promise((resolve, reject) => {
+        fetchjson(`${dir_url}/index.json`)
+            .then(json => {
+                Promise.all(
+                    json.map(async articlePath => {
+                        const art = await fetchjson(`${dir_url}/${articlePath}`);
+                        const tmpSplit = articlePath.split("/");
+                        tmpSplit.pop();
+                        const absArtPath = `${dir_url}/${tmpSplit.join("/")}`;
+                        return Object.assign(art, { path: absArtPath });
+                    })
+                )
+                    .then(articles => {
+                        populateArticles(articles)
+                            .then(completeArticles => resolve(completeArticles))
+                            .catch(e => reject(e));
+                    })
+                    .catch(e => reject(e));
+            })
+            .catch(e => console.log(e));
+    });
+}
+
+function populateArticles(articles) {
+    return new Promise((resolve, reject) => {
+        Promise.all(
+            articles.map(async article => {
+                if (article.body.indexOf("<file>") !== -1) {
+                    const txtPath = article.body.replace("<file>", "");
+                    const textValue = await fetchtext(`${article.path}/${txtPath}`);
+                    article.body = textValue;
+                    article.date = article.date ? new Date(article.date) : undefined;
+                }
+                return article;
+            })
+        )
+            .then(completeArticles => resolve(completeArticles.sort((a, b) => a.date - b.date)))
+            .catch(e => reject(e));
+    });
+}
+
+module.exports = {
+    loadArticles,
+    getArticleBody,
+    getArticleDate,
+    populateArticles,
+};
+
+},{"./fetch":5}],5:[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
+}
+
+},{}],6:[function(require,module,exports){
+"use strict";
+
 module.exports = {
     setRenderCycleRoot(renderCycleRoot) {
         this.renderCycleRoot = renderCycleRoot;
@@ -107,9 +272,179 @@ module.exports = {
     },
 };
 
-},{}],4:[function(require,module,exports){
+},{}],7:[function(require,module,exports){
+"use strict";
+
+const ImageCarousel = require("../../../generic-components/image-carousel");
+const { getArticleBody } = require("../../../lib/article-utils");
+
+class TeamMember {
+    constructor(props) {
+        this.props = props;
+    }
+
+    render() {
+        const { title, subtitle, body, images, path } = this.props;
+        return {
+            tag: "div",
+            class: "team-member",
+            contents: [
+                {
+                    tag: "div",
+                    class: "team-member-img",
+                    contents: [{ tag: "img", src: images.map(im => `${path}/images/${im}`)[0] }],
+                },
+                {
+                    tag: "h3",
+                    class: "team-member-title",
+                    contents: title,
+                },
+                {
+                    tag: "strong",
+                    class: "team-member-subtitle",
+                    contents: subtitle,
+                },
+                {
+                    tag: "p",
+                    class: "team-member-body",
+                    contents: getArticleBody(body),
+                },
+            ],
+        };
+    }
+}
+
+class GameArticle {
+    constructor(props) {
+        this.props = props;
+    }
+
+    render() {
+        const { title, tags, body, subtitle, images, path, team_subarticles } = this.props;
+        return {
+            tag: "article",
+            class: "game-article",
+            contents: [
+                {
+                    tag: "h2",
+                    class: "game-title",
+                    contents: title,
+                },
+                {
+                    tag: "div",
+                    class: "game-tags",
+                    contents: tags.map(tag => {
+                        return { tag: "span", contents: tag };
+                    }),
+                },
+                {
+                    tag: "h3",
+                    class: "game-subtitle",
+                    contents: subtitle,
+                },
+                {
+                    tag: "div",
+                    class: "game-description",
+                    contents: getArticleBody(body),
+                },
+                new ImageCarousel({ images: images.map(img => `${path}/images/${img}`) }).render(),
+                {
+                    tag: "div",
+                    class: "game-team",
+                    contents: [
+                        {
+                            tag: "h2",
+                            contents: "L'équipe",
+                        },
+                        {
+                            tag: "div",
+                            class: "team-members",
+                            contents: team_subarticles.map(tsa =>
+                                new TeamMember({ ...tsa }).render()
+                            ),
+                        },
+                    ],
+                },
+            ],
+        };
+    }
+}
+
+module.exports = GameArticle;
+
+},{"../../../generic-components/image-carousel":3,"../../../lib/article-utils":4}],8:[function(require,module,exports){
+"use strict";
+
+const { game_articles_url } = require("../../../../constants");
+const { loadArticles, populateArticles } = require("../../../lib/article-utils");
+const objectHtmlRenderer = require("../../../lib/object-html-renderer");
+const GameArticle = require("./game-article");
+
+class GameArticles {
+    constructor(props) {
+        this.props = props;
+        this.state = {
+            articles: [],
+        };
+        this.id = performance.now();
+        this.loadArticles();
+    }
+
+    loadArticles() {
+        loadArticles(game_articles_url)
+            .then(articles => {
+                Promise.all(
+                    articles.map(async a => {
+                        if (a.team_subarticles) {
+                            a.team_subarticles = await populateArticles(
+                                a.team_subarticles.map(sa => Object.assign(sa, { path: a.path }))
+                            );
+                        }
+                        return a;
+                    })
+                ).then(completeArticles => {
+                    this.state.articles = completeArticles;
+                    this.refresh();
+                });
+            })
+            .catch(e => console.log(e));
+    }
+
+    renderPlaceholder() {
+        return {
+            tag: "article",
+            class: "placeholder",
+            contents: [{ tag: "div" }, { tag: "div" }],
+        };
+    }
+
+    refresh() {
+        objectHtmlRenderer.subRender(this.render(), document.getElementById(this.id), {
+            mode: "replace",
+        });
+    }
+
+    render() {
+        const { articles } = this.state;
+        return {
+            tag: "section",
+            class: "game-articles page-contents-center",
+            id: this.id,
+            contents:
+                articles.length > 0
+                    ? articles.map(article => new GameArticle({ ...article }).render())
+                    : [this.renderPlaceholder()],
+        };
+    }
+}
+
+module.exports = GameArticles;
+
+},{"../../../../constants":2,"../../../lib/article-utils":4,"../../../lib/object-html-renderer":6,"./game-article":7}],9:[function(require,module,exports){
 "use strict";
 
+const GameArticles = require("./components/game-articles");
+
 class GamesPage {
     constructor(args) {
         Object.assign(this, args);
@@ -118,14 +453,22 @@ class GamesPage {
     render() {
         return {
             tag: "div",
+            id:"games-page",
             contents: [
                 {
                     tag: "div",
                     class: "page-header",
                     contents: [
-                        { tag: "h1", contents: "Jeux", class: "page-contents-center" }
+                        { tag: "h1", contents: "Jeux", class: "page-contents-center" },
+                        {
+                            tag: "p",
+                            class: "page-contents-center",
+                            contents: `Créer des jeux vidéos c'est cœur de ce qui nous passionne.
+                            <br/>Retrouvez ici nos créations, à jouer en ligne ou à télécharger, et découvrez nos projets en cours.`,
+                        },
                     ],
                 },
+                new GameArticles().render(),
             ],
         };
     }
@@ -133,7 +476,7 @@ class GamesPage {
 
 module.exports = GamesPage;
 
-},{}],5:[function(require,module,exports){
+},{"./components/game-articles":8}],10:[function(require,module,exports){
 "use strict";
 
 "use strict";
@@ -141,7 +484,7 @@ const runPage = require("../../run-page");
 const GamesPage = require("./games");
 runPage(GamesPage);
 
-},{"../../run-page":6,"./games":4}],6:[function(require,module,exports){
+},{"../../run-page":11,"./games":9}],11:[function(require,module,exports){
 "use strict";
 
 const objectHtmlRenderer = require("./lib/object-html-renderer");
@@ -153,7 +496,7 @@ module.exports = function runPage(PageComponent) {
     objectHtmlRenderer.renderCycle();
 };
 
-},{"./lib/object-html-renderer":3,"./template/template":8}],7:[function(require,module,exports){
+},{"./lib/object-html-renderer":6,"./template/template":13}],12:[function(require,module,exports){
 "use strict";
 
 const { images_url } = require("../../../constants");
@@ -259,9 +602,10 @@ class NavBar {
 
 module.exports = NavBar;
 
-},{"../../../constants":2}],8:[function(require,module,exports){
+},{"../../../constants":2}],13:[function(require,module,exports){
 "use strict";
 
+const { in_construction } = require("../../config");
 const { images_url } = require("../../constants");
 const NavBar = require("./components/navbar");
 
@@ -277,8 +621,19 @@ class Template {
                     tag: "header",
                     contents: [new NavBar().render()],
                 },
+                in_construction && {
+                    tag: "section",
+                    class: "warning-banner",
+                    contents: [
+                        {
+                            tag: "strong",
+                            class: "page-contents-center",
+                            contents: "Site en construction ...",
+                        },
+                    ],
+                },
                 {
-                    tag: "div",
+                    tag: "section",
                     id: "page-container",
                     contents: [this.props.page.render()],
                 },
@@ -295,14 +650,15 @@ class Template {
                                 },
                                 {
                                     tag: "img",
-                                    class:"text-logo",
+                                    class: "text-logo",
                                     src: `${images_url}/logo_kuadrado_txt.svg`,
                                 },
                             ],
                         },
                         {
-                            tag:"span",
-                            contents: "Toutes les images du site ont été réalisées par nos soins et peuvent être réutilisées pour un usage personnel."
+                            tag: "span",
+                            contents:
+                                "Toutes les images du site ont été réalisées par nos soins et peuvent être réutilisées pour un usage personnel.",
                         },
                         {
                             tag: "a",
@@ -318,4 +674,4 @@ class Template {
 
 module.exports = Template;
 
-},{"../../constants":2,"./components/navbar":7}]},{},[5]);
+},{"../../config":1,"../../constants":2,"./components/navbar":12}]},{},[10]);
diff --git a/public/main.js b/public/main.js
index accb62f23d9a11b9fc15850565cd50bb210ca459..523eb03fbc5a086a49bf5644a2854534c85a1b2f 100644
--- a/public/main.js
+++ b/public/main.js
@@ -11,25 +11,92 @@ switch (ENV) {
         server_url = "http://kuadrado-software.fr";
 }
 
-module.exports = { server_url };
+module.exports = { server_url, in_construction: true };
 
 },{}],2:[function(require,module,exports){
 const { server_url } = require("./config");
 
 module.exports = {
     images_url: `${server_url}/assets/images`,
-    articles_url: `${server_url}/articles`,
+    news_articles_url: `${server_url}/news-articles`,
+    game_articles_url: `${server_url}/game-articles`,
+    software_articles_url: `${server_url}/software-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 {
+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] },
+                images.length > 1 && {
+                    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":9}],4:[function(require,module,exports){
+"use strict";
+
+const { news_articles_url } = require("../../constants");
+const objectHtmlRenderer = require("../lib/object-html-renderer");
+const ImageCarousel = require("../generic-components/image-carousel");
+const { loadArticles, getArticleDate, getArticleBody } = require("../lib/article-utils");
+
+class NewsArticles {
     constructor() {
         this.id = performance.now().toString();
         this.state = {
@@ -41,35 +108,11 @@ class Articles {
     }
 
     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();
+        loadArticles(news_articles_url).then(articles => {
+            this.state.articles = articles;
+            this.state.showArticleIndex = this.state.articles.length - 1;
+            this.refresh();
+        });
     }
 
     refresh() {
@@ -78,25 +121,6 @@ class Articles {
         });
     }
 
-    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",
@@ -104,7 +128,7 @@ class Articles {
                 {
                     tag: "div",
                     class: "date",
-                    contents: [{ tag: "span", contents: this.getArticleDate(articleData.date) }],
+                    contents: [{ tag: "span", contents: getArticleDate(articleData.date) }],
                 },
                 {
                     tag: "div",
@@ -132,7 +156,7 @@ class Articles {
                     contents: [
                         {
                             tag: "p",
-                            contents: this.getArticleBody(articleData.content_text),
+                            contents: getArticleBody(articleData.body),
                         },
                     ],
                 },
@@ -182,91 +206,34 @@ class Articles {
             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"),
+                              tag: "div",
+                              class: "prev-next-buttons",
+                              contents: [
+                                  {
+                                      tag: "button",
+                                      class: `prev-btn ${!showPrev ? "disabled" : "active"}`,
+                                      contents: "Précédent",
+                                      onclick: this.handleChangeArticle.bind(this, "prev"),
+                                  },
+                                  {
+                                      tag: "button",
+                                      class: `next-btn ${!showNext ? "disabled" : "active"}`,
+                                      contents: "Suivant",
+                                      onclick: this.handleChangeArticle.bind(this, "next"),
+                                  },
+                              ],
                           },
                       ]
-                    : [{tag:"div"},this.renderArticlePlaceholder(), {tag:"div"}],
+                    : [this.renderArticlePlaceholder()],
         };
     }
 }
 
-module.exports = Articles;
+module.exports = NewsArticles;
 
-},{"../../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){
+},{"../../constants":2,"../generic-components/image-carousel":3,"../lib/article-utils":7,"../lib/object-html-renderer":9}],5:[function(require,module,exports){
 "use strict";
 
 const { images_url } = require("../../constants");
@@ -307,7 +274,8 @@ module.exports = ThemeCard;
 },{"../../constants":2}],6:[function(require,module,exports){
 "use strict";
 
-const Articles = require("./home-page-components/articles");
+const { images_url } = require("../constants");
+const NewsArticles = require("./home-page-components/news-articles");
 const ThemeCard = require("./home-page-components/theme-card");
 
 class HomePage {
@@ -324,6 +292,18 @@ class HomePage {
                     tag: "div",
                     class: "page-header",
                     contents: [
+                        {
+                            tag: "div",
+                            class: "big-logo page-contents-center",
+                            contents: [
+                                { tag: "img", src: `${images_url}/logo_kuadrado.svg` },
+                                {
+                                    tag: "img",
+                                    class: "logo-text",
+                                    src: `${images_url}/logo_kuadrado_txt.svg`,
+                                },
+                            ],
+                        },
                         { tag: "h1", contents: "Kuadrado Software", class: "page-contents-center" },
                         {
                             tag: "p",
@@ -340,7 +320,7 @@ class HomePage {
                     class: "page-contents-center",
                     contents: [
                         { tag: "h2", contents: "Actu", class: "section-title bg-blue" },
-                        new Articles().render(),
+                        new NewsArticles().render(),
                     ],
                 },
                 {
@@ -377,7 +357,80 @@ class HomePage {
 
 module.exports = HomePage;
 
-},{"./home-page-components/articles":3,"./home-page-components/theme-card":5}],7:[function(require,module,exports){
+},{"../constants":2,"./home-page-components/news-articles":4,"./home-page-components/theme-card":5}],7:[function(require,module,exports){
+"use strict";
+
+const { fetchjson, fetchtext } = require("./fetch");
+
+function getArticleBody(text) {
+    return text
+        .split(" ")
+        .map(word => {
+            if (word.includes("http://") || word.includes("https://")) {
+                const splitword = word.split("||");
+                const href = splitword[0].match(/http.+/);
+                const text = splitword.length > 1 ? splitword[1].replaceAll("_", " ") : href;
+                return word.replace(/http.*/, `<a href=${href} target="_blank">${text}</a>`);
+            } else return word;
+        })
+        .join(" ")
+        .replaceAll("\n", "<br/>");
+}
+
+function getArticleDate(date) {
+    return `${date.getDate()}-${date.getMonth() + 1}-${date.getFullYear()}`;
+}
+
+function loadArticles(dir_url) {
+    return new Promise((resolve, reject) => {
+        fetchjson(`${dir_url}/index.json`)
+            .then(json => {
+                Promise.all(
+                    json.map(async articlePath => {
+                        const art = await fetchjson(`${dir_url}/${articlePath}`);
+                        const tmpSplit = articlePath.split("/");
+                        tmpSplit.pop();
+                        const absArtPath = `${dir_url}/${tmpSplit.join("/")}`;
+                        return Object.assign(art, { path: absArtPath });
+                    })
+                )
+                    .then(articles => {
+                        populateArticles(articles)
+                            .then(completeArticles => resolve(completeArticles))
+                            .catch(e => reject(e));
+                    })
+                    .catch(e => reject(e));
+            })
+            .catch(e => console.log(e));
+    });
+}
+
+function populateArticles(articles) {
+    return new Promise((resolve, reject) => {
+        Promise.all(
+            articles.map(async article => {
+                if (article.body.indexOf("<file>") !== -1) {
+                    const txtPath = article.body.replace("<file>", "");
+                    const textValue = await fetchtext(`${article.path}/${txtPath}`);
+                    article.body = textValue;
+                    article.date = article.date ? new Date(article.date) : undefined;
+                }
+                return article;
+            })
+        )
+            .then(completeArticles => resolve(completeArticles.sort((a, b) => a.date - b.date)))
+            .catch(e => reject(e));
+    });
+}
+
+module.exports = {
+    loadArticles,
+    getArticleBody,
+    getArticleDate,
+    populateArticles,
+};
+
+},{"./fetch":8}],8:[function(require,module,exports){
 "use strict";
 
 function fetchjson(url) {
@@ -402,7 +455,7 @@ module.exports = {
     fetchjson, fetchtext
 }
 
-},{}],8:[function(require,module,exports){
+},{}],9:[function(require,module,exports){
 "use strict";
 
 module.exports = {
@@ -488,7 +541,7 @@ module.exports = {
     },
 };
 
-},{}],9:[function(require,module,exports){
+},{}],10:[function(require,module,exports){
 "use strict";
 
 const HomePage = require("./homepage");
@@ -496,7 +549,7 @@ const runPage = require("./run-page");
 
 runPage(HomePage);
 
-},{"./homepage":6,"./run-page":10}],10:[function(require,module,exports){
+},{"./homepage":6,"./run-page":11}],11:[function(require,module,exports){
 "use strict";
 
 const objectHtmlRenderer = require("./lib/object-html-renderer");
@@ -508,7 +561,7 @@ module.exports = function runPage(PageComponent) {
     objectHtmlRenderer.renderCycle();
 };
 
-},{"./lib/object-html-renderer":8,"./template/template":12}],11:[function(require,module,exports){
+},{"./lib/object-html-renderer":9,"./template/template":13}],12:[function(require,module,exports){
 "use strict";
 
 const { images_url } = require("../../../constants");
@@ -614,9 +667,10 @@ class NavBar {
 
 module.exports = NavBar;
 
-},{"../../../constants":2}],12:[function(require,module,exports){
+},{"../../../constants":2}],13:[function(require,module,exports){
 "use strict";
 
+const { in_construction } = require("../../config");
 const { images_url } = require("../../constants");
 const NavBar = require("./components/navbar");
 
@@ -632,8 +686,19 @@ class Template {
                     tag: "header",
                     contents: [new NavBar().render()],
                 },
+                in_construction && {
+                    tag: "section",
+                    class: "warning-banner",
+                    contents: [
+                        {
+                            tag: "strong",
+                            class: "page-contents-center",
+                            contents: "Site en construction ...",
+                        },
+                    ],
+                },
                 {
-                    tag: "div",
+                    tag: "section",
                     id: "page-container",
                     contents: [this.props.page.render()],
                 },
@@ -650,14 +715,15 @@ class Template {
                                 },
                                 {
                                     tag: "img",
-                                    class:"text-logo",
+                                    class: "text-logo",
                                     src: `${images_url}/logo_kuadrado_txt.svg`,
                                 },
                             ],
                         },
                         {
-                            tag:"span",
-                            contents: "Toutes les images du site ont été réalisées par nos soins et peuvent être réutilisées pour un usage personnel."
+                            tag: "span",
+                            contents:
+                                "Toutes les images du site ont été réalisées par nos soins et peuvent être réutilisées pour un usage personnel.",
                         },
                         {
                             tag: "a",
@@ -673,4 +739,4 @@ class Template {
 
 module.exports = Template;
 
-},{"../../constants":2,"./components/navbar":11}]},{},[9]);
+},{"../../config":1,"../../constants":2,"./components/navbar":12}]},{},[10]);
diff --git a/public/articles/index.json b/public/news-articles/index.json
similarity index 100%
rename from public/articles/index.json
rename to public/news-articles/index.json
diff --git a/public/articles/nested/article-nested.json b/public/news-articles/nested/article-nested.json
similarity index 81%
rename from public/articles/nested/article-nested.json
rename to public/news-articles/nested/article-nested.json
index 8c147f61e8ffe0e4e48892d2aef83892ce07e6ea..7fc343b351e3e2195db56bfaa655197da2d785f7 100644
--- a/public/articles/nested/article-nested.json
+++ b/public/news-articles/nested/article-nested.json
@@ -2,6 +2,6 @@
     "title": "Kuadrado Software mange des burgers",
     "date": "1954/02/25",
     "subtitle": "Ouaiis on est vraiment contents",
-    "content_text": "<file>my-content-text.txt",
+    "body": "<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/news-articles/nested/images/screen_1.png
similarity index 100%
rename from public/articles/nested/images/screen_1.png
rename to public/news-articles/nested/images/screen_1.png
diff --git a/public/articles/nested/images/screen_2.png b/public/news-articles/nested/images/screen_2.png
similarity index 100%
rename from public/articles/nested/images/screen_2.png
rename to public/news-articles/nested/images/screen_2.png
diff --git a/public/articles/nested/images/screen_3.png b/public/news-articles/nested/images/screen_3.png
similarity index 100%
rename from public/articles/nested/images/screen_3.png
rename to public/news-articles/nested/images/screen_3.png
diff --git a/public/articles/nested/images/screen_4.png b/public/news-articles/nested/images/screen_4.png
similarity index 100%
rename from public/articles/nested/images/screen_4.png
rename to public/news-articles/nested/images/screen_4.png
diff --git a/public/articles/nested/my-content-text.txt b/public/news-articles/nested/my-content-text.txt
similarity index 100%
rename from public/articles/nested/my-content-text.txt
rename to public/news-articles/nested/my-content-text.txt
diff --git a/public/articles/test/article-test.json b/public/news-articles/test/article-test.json
similarity index 86%
rename from public/articles/test/article-test.json
rename to public/news-articles/test/article-test.json
index a2afa7c8e7bafa66610c2a1f65f7b152d40a7ba4..ed7c6ac63937bec0c84f431aea10c445bbf50cea 100644
--- a/public/articles/test/article-test.json
+++ b/public/news-articles/test/article-test.json
@@ -2,7 +2,7 @@
     "title": "Kuadrado Software ouvre ses portes",
     "date": "2032/08/25",
     "subtitle": "Ouaiis on est vraiment contents",
-    "content_text": "<file>content-text.txt",
+    "body": "<file>content-text.txt",
     "images": [
         "screen_l1_1.jpg",
         "screen_l1_2.jpg",
diff --git a/public/articles/test/content-text.txt b/public/news-articles/test/content-text.txt
similarity index 100%
rename from public/articles/test/content-text.txt
rename to public/news-articles/test/content-text.txt
diff --git a/public/articles/test/images/screen_l1_1.jpg b/public/news-articles/test/images/screen_l1_1.jpg
similarity index 100%
rename from public/articles/test/images/screen_l1_1.jpg
rename to public/news-articles/test/images/screen_l1_1.jpg
diff --git a/public/articles/test/images/screen_l1_2.jpg b/public/news-articles/test/images/screen_l1_2.jpg
similarity index 100%
rename from public/articles/test/images/screen_l1_2.jpg
rename to public/news-articles/test/images/screen_l1_2.jpg
diff --git a/public/articles/test/images/screen_l2.jpg b/public/news-articles/test/images/screen_l2.jpg
similarity index 100%
rename from public/articles/test/images/screen_l2.jpg
rename to public/news-articles/test/images/screen_l2.jpg
diff --git a/public/articles/test/images/screen_l3.jpg b/public/news-articles/test/images/screen_l3.jpg
similarity index 100%
rename from public/articles/test/images/screen_l3.jpg
rename to public/news-articles/test/images/screen_l3.jpg
diff --git a/public/articles/test/images/screen_secret.jpg b/public/news-articles/test/images/screen_secret.jpg
similarity index 100%
rename from public/articles/test/images/screen_secret.jpg
rename to public/news-articles/test/images/screen_secret.jpg
diff --git a/public/software-articles/index.json b/public/software-articles/index.json
new file mode 100644
index 0000000000000000000000000000000000000000..0637a088a01e8ddab3bf3fa98dbe804cbde1a0dc
--- /dev/null
+++ b/public/software-articles/index.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/public/software-development/software-development.js b/public/software-development/software-development.js
index a3470c5597d37b553dee011dadbc611af708ce8b..277576e7b60d69e058267fb083eeed73da82106a 100644
--- a/public/software-development/software-development.js
+++ b/public/software-development/software-development.js
@@ -11,14 +11,16 @@ switch (ENV) {
         server_url = "http://kuadrado-software.fr";
 }
 
-module.exports = { server_url };
+module.exports = { server_url, in_construction: true };
 
 },{}],2:[function(require,module,exports){
 const { server_url } = require("./config");
 
 module.exports = {
     images_url: `${server_url}/assets/images`,
-    articles_url: `${server_url}/articles`,
+    news_articles_url: `${server_url}/news-articles`,
+    game_articles_url: `${server_url}/game-articles`,
+    software_articles_url: `${server_url}/software-articles`,
 };
 
 },{"./config":1}],3:[function(require,module,exports){
@@ -260,6 +262,7 @@ module.exports = NavBar;
 },{"../../../constants":2}],8:[function(require,module,exports){
 "use strict";
 
+const { in_construction } = require("../../config");
 const { images_url } = require("../../constants");
 const NavBar = require("./components/navbar");
 
@@ -275,8 +278,19 @@ class Template {
                     tag: "header",
                     contents: [new NavBar().render()],
                 },
+                in_construction && {
+                    tag: "section",
+                    class: "warning-banner",
+                    contents: [
+                        {
+                            tag: "strong",
+                            class: "page-contents-center",
+                            contents: "Site en construction ...",
+                        },
+                    ],
+                },
                 {
-                    tag: "div",
+                    tag: "section",
                     id: "page-container",
                     contents: [this.props.page.render()],
                 },
@@ -293,14 +307,15 @@ class Template {
                                 },
                                 {
                                     tag: "img",
-                                    class:"text-logo",
+                                    class: "text-logo",
                                     src: `${images_url}/logo_kuadrado_txt.svg`,
                                 },
                             ],
                         },
                         {
-                            tag:"span",
-                            contents: "Toutes les images du site ont été réalisées par nos soins et peuvent être réutilisées pour un usage personnel."
+                            tag: "span",
+                            contents:
+                                "Toutes les images du site ont été réalisées par nos soins et peuvent être réutilisées pour un usage personnel.",
                         },
                         {
                             tag: "a",
@@ -316,4 +331,4 @@ class Template {
 
 module.exports = Template;
 
-},{"../../constants":2,"./components/navbar":7}]},{},[5]);
+},{"../../config":1,"../../constants":2,"./components/navbar":7}]},{},[5]);
diff --git a/public/style/homepage.css b/public/style/homepage.css
index b62211788fbfc53f0f8a32dab02bd7751ab679c4..4376425cad2370421d7ab814e02caa62fab70caf 100644
--- a/public/style/homepage.css
+++ b/public/style/homepage.css
@@ -1,9 +1,9 @@
-/* Error: Undefined variable.
+/* Error: Undefined mixin.
  *   ,
- * 9 |         background-color: $light_0;
- *   |                           ^^^^^^^^
+ * 8 |             @include flex-center;
+ *   |             ^^^^^^^^^^^^^^^^^^^^
  *   '
- *   src/homepage.scss 9:27  root stylesheet */
+ *   src/homepage.scss 8:13  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 9 \2502          background-color: $light_0;\a   \2502                            ^^^^^^^^\a   \2575 \a   src/homepage.scss 9:27  root stylesheet";
+  content: "Error: Undefined mixin.\a   \2577 \a 8 \2502              @include flex-center;\a   \2502              ^^^^^^^^^^^^^^^^^^^^\a   \2575 \a   src/homepage.scss 8:13  root stylesheet";
 }
diff --git a/public/style/pages/games/games.css b/public/style/pages/games/games.css
new file mode 100644
index 0000000000000000000000000000000000000000..a172391064087fc34a6de0b591042e19bc1d77b9
--- /dev/null
+++ b/public/style/pages/games/games.css
@@ -0,0 +1,17 @@
+/* Error: Undefined variable.
+ *    ,
+ * 10 |                 background-color: $dark_2;
+ *    |                                   ^^^^^^^
+ *    '
+ *   src/pages/games/games.scss 10:35  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 10 \2502                  background-color: $dark_2;\a    \2502                                    ^^^^^^^\a    \2575 \a   src/pages/games/games.scss 10:35  root stylesheet";
+}
diff --git a/public/style/style.css b/public/style/style.css
index c498e8b5416c990d2a06ddaabbf6c5538660103e..6866c243acd807e659a167021a9aed1af0304151 100644
--- a/public/style/style.css
+++ b/public/style/style.css
@@ -36,6 +36,64 @@ main {
   align-items: center;
   min-height: 100vh;
 }
+main .warning-banner {
+  background: url("/assets/images/wallpaper_warning.svg");
+  width: 100%;
+  height: 40px;
+  padding: 20px 10%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex-direction: row;
+}
+main .warning-banner strong {
+  font-size: 18px;
+  color: #1c3db2;
+}
+main .image-carousel {
+  overflow: hidden;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex-direction: row;
+  background-color: black;
+  position: relative;
+}
+main .image-carousel img {
+  position: absolute;
+  max-width: 100%;
+  max-height: 400px;
+}
+main .image-carousel .carousel-bullets {
+  position: absolute;
+  bottom: 0;
+  padding: 20px;
+  display: flex;
+  gap: 10px;
+}
+main .image-carousel .carousel-bullets .bullet {
+  cursor: pointer;
+  width: 8px;
+  height: 8px;
+  background-color: #6b7880;
+  border-radius: 100%;
+  box-shadow: 0 0 3px black;
+}
+main .image-carousel .carousel-bullets .bullet.active {
+  background-color: #d4d9dd;
+}
+@media screen and (max-width: 900px) {
+  main .image-carousel img {
+    max-height: 100%;
+  }
+  main .image-carousel .carousel-bullets {
+    gap: 15px;
+  }
+  main .image-carousel .carousel-bullets .bullet {
+    width: 12px;
+    height: 12px;
+  }
+}
 main header {
   width: 100%;
 }
@@ -95,7 +153,7 @@ main header nav ul li .submenu {
 }
 main header nav ul li.active a {
   color: #3c4144;
-  border-bottom: 1px solid;
+  border-bottom: 2px solid;
 }
 main header nav ul li:hover a {
   color: #3c4144;
@@ -175,7 +233,7 @@ main #page-container {
 }
 main #page-container .page-header {
   background-image: url("/assets/images/wallpaper_binary.png");
-  padding: 10px 0;
+  padding: 50px 0;
 }
 main #page-container .page-header h1 {
   padding: 15px 40px 0;
@@ -197,7 +255,8 @@ main #page-container .page-header p * {
     padding: 15px 20px 0;
   }
   main #page-container .page-header p {
-    padding: 15px;
+    padding: 20px 20px 30px 40px;
+    text-align: justify;
   }
 }
 main #page-container .page-contents-center {
@@ -211,6 +270,27 @@ main #page-container #home-page {
   gap: 20px;
   margin-bottom: 60px;
 }
+main #page-container #home-page .page-header .big-logo {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex-direction: row;
+  gap: 20px;
+  padding: 20px;
+}
+main #page-container #home-page .page-header .big-logo img {
+  width: 200px;
+  max-width: 100%;
+}
+main #page-container #home-page .page-header .big-logo img.logo-text {
+  width: 300px;
+  max-width: 100%;
+}
+@media screen and (max-width: 560px) {
+  main #page-container #home-page .page-header .big-logo {
+    flex-direction: column;
+  }
+}
 main #page-container #home-page .section-title {
   padding: 10px;
   margin: 0;
@@ -219,53 +299,57 @@ main #page-container #home-page .section-title {
 }
 main #page-container #home-page .articles-displayer {
   margin: 0 auto 40px;
-  display: grid;
-  grid-template-columns: 50px auto 50px;
 }
-main #page-container #home-page .articles-displayer .prev-btn,
-main #page-container #home-page .articles-displayer .next-btn {
+main #page-container #home-page .articles-displayer .prev-next-buttons {
+  display: flex;
+  justify-content: space-between;
+}
+main #page-container #home-page .articles-displayer .prev-next-buttons .prev-btn,
+main #page-container #home-page .articles-displayer .prev-next-buttons .next-btn {
   border: none;
-  background-image: url("/assets/images/wallpaper_binary.png");
+  background: none;
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  padding: 5px 0;
 }
-main #page-container #home-page .articles-displayer .prev-btn.disabled,
-main #page-container #home-page .articles-displayer .next-btn.disabled {
+main #page-container #home-page .articles-displayer .prev-next-buttons .prev-btn.disabled,
+main #page-container #home-page .articles-displayer .prev-next-buttons .next-btn.disabled {
+  visibility: hidden;
   pointer-events: none;
 }
-main #page-container #home-page .articles-displayer .prev-btn.active,
-main #page-container #home-page .articles-displayer .next-btn.active {
+main #page-container #home-page .articles-displayer .prev-next-buttons .prev-btn.active,
+main #page-container #home-page .articles-displayer .prev-next-buttons .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 .prev-next-buttons .prev-btn.active:hover,
+main #page-container #home-page .articles-displayer .prev-next-buttons .next-btn.active:hover {
+  color: #3c4144;
 }
-main #page-container #home-page .articles-displayer .next-btn.active::before {
+main #page-container #home-page .articles-displayer .prev-next-buttons .next-btn.active::after {
   content: " ";
   border-style: solid;
-  border-width: 4px 4px 0 0;
-  width: 20px;
-  height: 20px;
+  border-width: 2px 2px 0 0;
+  width: 8px;
+  height: 8px;
   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 {
+main #page-container #home-page .articles-displayer .prev-next-buttons .prev-btn.active::before {
   content: " ";
   border-style: solid;
-  border-width: 4px 4px 0 0;
-  width: 20px;
-  height: 20px;
+  border-width: 2px 2px 0 0;
+  width: 8px;
+  height: 8px;
   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;
@@ -303,40 +387,11 @@ main #page-container #home-page .articles-displayer article .body {
   grid-row: 4;
   min-height: 250px;
   padding-bottom: 40px;
+  text-align: justify;
 }
 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%;
-  max-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;
@@ -354,9 +409,6 @@ main #page-container #home-page .articles-displayer article.article-placeholder
   height: 30px;
 }
 @media screen and (max-width: 900px) {
-  main #page-container #home-page .articles-displayer {
-    grid-template-columns: 40px auto 40px;
-  }
   main #page-container #home-page .articles-displayer article {
     gap: 5px;
     grid-template-columns: 1fr;
@@ -383,16 +435,6 @@ main #page-container #home-page .articles-displayer article.article-placeholder
     grid-row: 1;
     grid-column: 1;
   }
-  main #page-container #home-page .articles-displayer article .image-carousel img {
-    max-height: 100%;
-  }
-  main #page-container #home-page .articles-displayer article .image-carousel .carousel-bullets {
-    gap: 15px;
-  }
-  main #page-container #home-page .articles-displayer article .image-carousel .carousel-bullets .bullet {
-    width: 12px;
-    height: 12px;
-  }
 }
 main #page-container #home-page .grid-3 {
   gap: 30px;
@@ -432,7 +474,7 @@ main #page-container #home-page .grid-3 .theme-card .card-title h2 {
 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;
+  padding: 30px 20px;
 }
 main #page-container #home-page .grid-3 .theme-card .card-description p {
   margin: 0;
@@ -463,7 +505,7 @@ main #page-container #home-page .grid-3 .theme-card:hover {
   main #page-container #home-page .grid-3 .theme-card .card-description {
     background-image: url("/assets/images/wallpaper_binary.png");
     flex: 1;
-    padding: 10px 10px 20px;
+    padding: 20px 30px;
   }
   main #page-container #home-page .grid-3 .theme-card .card-description p {
     margin: 0;
@@ -737,6 +779,137 @@ main #page-container #education-page .section-contents .infos-inscriptions .pric
     padding: 10px;
   }
 }
+main #page-container #games-page .game-articles article {
+  display: grid;
+  grid-template-columns: 0.7fr 1fr;
+  gap: 0 20px;
+  margin: 20px;
+}
+main #page-container #games-page .game-articles article.game-article {
+  grid-template-rows: repeat(6, auto);
+  background-color: #3c4144;
+}
+main #page-container #games-page .game-articles article.game-article *:not(a) {
+  color: #d4d9dd;
+}
+main #page-container #games-page .game-articles article.game-article .game-title {
+  grid-column: 1/span 2;
+  background-color: #d4d9dd;
+  margin: 0;
+  padding: 30px 20px;
+  color: #6b7880;
+  font-size: 35px;
+  font-style: italic;
+}
+main #page-container #games-page .game-articles article.game-article .game-tags {
+  grid-column: 1;
+  display: flex;
+  gap: 10px;
+  flex-wrap: wrap;
+  margin: 10px 20px;
+}
+main #page-container #games-page .game-articles article.game-article .game-tags span {
+  font-size: 12px;
+  padding: 6px;
+  background-color: #ffd000;
+  color: #6b7880;
+  border-radius: 5px;
+  font-weight: 600;
+}
+main #page-container #games-page .game-articles article.game-article .game-subtitle {
+  grid-column: 1;
+  margin: 10px 20px 30px;
+}
+main #page-container #games-page .game-articles article.game-article .game-description {
+  grid-column: 1;
+  text-align: justify;
+  margin: 10px 20px 30px;
+}
+main #page-container #games-page .game-articles article.game-article .image-carousel {
+  grid-column: 2;
+  grid-row: 2/span 4;
+  height: 400px;
+}
+main #page-container #games-page .game-articles article.game-article .game-team {
+  grid-column: 1/span 2;
+}
+main #page-container #games-page .game-articles article.game-article .game-team h2 {
+  background-color: #d4d9dd;
+  color: #6b7880;
+  padding: 10px 20px;
+  font-style: italic;
+  font-size: 20px;
+  margin: 0;
+}
+main #page-container #games-page .game-articles article.game-article .game-team .team-members {
+  display: flex;
+  flex-direction: column;
+  gap: 30px;
+}
+main #page-container #games-page .game-articles article.game-article .game-team .team-members .team-member {
+  display: grid;
+  grid-template-columns: 150px 1fr;
+  grid-template-rows: auto auto 1fr;
+}
+main #page-container #games-page .game-articles article.game-article .game-team .team-members .team-member .team-member-img {
+  grid-row: 1/span 3;
+  overflow: hidden;
+}
+main #page-container #games-page .game-articles article.game-article .game-team .team-members .team-member .team-member-img img {
+  image-rendering: crisp-edges;
+  image-rendering: -moz-crisp-edges;
+  image-rendering: pixelated;
+  width: 100%;
+}
+main #page-container #games-page .game-articles article.game-article .game-team .team-members .team-member .team-member-title {
+  margin: 10px 10px 5px;
+}
+main #page-container #games-page .game-articles article.game-article .game-team .team-members .team-member .team-member-subtitle {
+  margin: 0 10px;
+  font-size: 14px;
+  color: #96a5ae;
+  font-style: italic;
+}
+main #page-container #games-page .game-articles article.game-article .game-team .team-members .team-member .team-member-body {
+  margin: 20px 10px 20px 30px;
+  text-align: justify;
+}
+main #page-container #games-page .game-articles article.placeholder {
+  height: 400px;
+}
+main #page-container #games-page .game-articles article.placeholder * {
+  background-color: #d4d9dd;
+}
+@media screen and (max-width: 900px) {
+  main #page-container #games-page .game-articles article {
+    grid-template-columns: 1fr;
+  }
+  main #page-container #games-page .game-articles article.game-article {
+    grid-template-rows: repeat(5, auto);
+  }
+  main #page-container #games-page .game-articles article.game-article .game-title {
+    grid-column: 1;
+    padding: 20px;
+    font-size: 25px;
+  }
+  main #page-container #games-page .game-articles article.game-article .image-carousel {
+    grid-column: 1;
+    grid-row: 2;
+  }
+  main #page-container #games-page .game-articles article.game-article .game-team {
+    grid-column: 1;
+  }
+  main #page-container #games-page .game-articles article.game-article .game-team .team-members .team-member {
+    grid-template-columns: 70px 1fr;
+  }
+  main #page-container #games-page .game-articles article.game-article .game-team .team-members .team-member .team-member-img {
+    grid-row: 1/span 2;
+    margin: 10px;
+  }
+  main #page-container #games-page .game-articles article.game-article .game-team .team-members .team-member .team-member-body {
+    grid-column: 1/span 2;
+  }
+}
 main footer {
   display: flex;
   justify-content: center;
@@ -745,12 +918,13 @@ main footer {
   flex-direction: column;
   width: 100%;
   background-image: url("/assets/images/wallpaper_binary.png");
-  padding: 20px;
+  padding: 40px 20px;
   gap: 20px;
   font-size: 12px;
 }
 main footer span {
   color: #96a5ae;
+  text-align: center;
 }
 main footer .logo {
   display: flex;
diff --git a/src/home-page-components/image-carousel.js b/src/generic-components/image-carousel.js
similarity index 97%
rename from src/home-page-components/image-carousel.js
rename to src/generic-components/image-carousel.js
index f32b41c70bc4a0471442a493806df662eb2b69b3..531caa68828c88ecc4df23a370c9d32f254506ed 100644
--- a/src/home-page-components/image-carousel.js
+++ b/src/generic-components/image-carousel.js
@@ -43,7 +43,7 @@ class ImageCarousel {
             class: "image-carousel",
             contents: [
                 { tag: "img", src: images[showImageIndex] },
-                {
+                images.length > 1 && {
                     tag: "div",
                     class: "carousel-bullets",
                     contents: images.map((_, i) => {
diff --git a/src/home-page-components/articles.js b/src/home-page-components/news-articles.js
similarity index 52%
rename from src/home-page-components/articles.js
rename to src/home-page-components/news-articles.js
index ee3dd7e64d35db8930ea873556fa6b6db304df4d..57eacfb7a5a7b5f7192fed5538fff1e5d23cf9d4 100644
--- a/src/home-page-components/articles.js
+++ b/src/home-page-components/news-articles.js
@@ -1,11 +1,11 @@
 "use strict";
 
-const { articles_url } = require("../../constants");
-const { fetchjson, fetchtext } = require("../lib/fetch");
+const { news_articles_url } = require("../../constants");
 const objectHtmlRenderer = require("../lib/object-html-renderer");
-const ImageCarousel = require("./image-carousel");
+const ImageCarousel = require("../generic-components/image-carousel");
+const { loadArticles, getArticleDate, getArticleBody } = require("../lib/article-utils");
 
-class Articles {
+class NewsArticles {
     constructor() {
         this.id = performance.now().toString();
         this.state = {
@@ -17,35 +17,11 @@ class Articles {
     }
 
     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();
+        loadArticles(news_articles_url).then(articles => {
+            this.state.articles = articles;
+            this.state.showArticleIndex = this.state.articles.length - 1;
+            this.refresh();
+        });
     }
 
     refresh() {
@@ -54,25 +30,6 @@ class Articles {
         });
     }
 
-    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",
@@ -80,7 +37,7 @@ class Articles {
                 {
                     tag: "div",
                     class: "date",
-                    contents: [{ tag: "span", contents: this.getArticleDate(articleData.date) }],
+                    contents: [{ tag: "span", contents: getArticleDate(articleData.date) }],
                 },
                 {
                     tag: "div",
@@ -108,7 +65,7 @@ class Articles {
                     contents: [
                         {
                             tag: "p",
-                            contents: this.getArticleBody(articleData.content_text),
+                            contents: getArticleBody(articleData.body),
                         },
                     ],
                 },
@@ -158,21 +115,29 @@ class Articles {
             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"),
+                              tag: "div",
+                              class: "prev-next-buttons",
+                              contents: [
+                                  {
+                                      tag: "button",
+                                      class: `prev-btn ${!showPrev ? "disabled" : "active"}`,
+                                      contents: "Précédent",
+                                      onclick: this.handleChangeArticle.bind(this, "prev"),
+                                  },
+                                  {
+                                      tag: "button",
+                                      class: `next-btn ${!showNext ? "disabled" : "active"}`,
+                                      contents: "Suivant",
+                                      onclick: this.handleChangeArticle.bind(this, "next"),
+                                  },
+                              ],
                           },
                       ]
-                    : [{tag:"div"},this.renderArticlePlaceholder(), {tag:"div"}],
+                    : [this.renderArticlePlaceholder()],
         };
     }
 }
 
-module.exports = Articles;
+module.exports = NewsArticles;
diff --git a/src/homepage.js b/src/homepage.js
index a7b183010d17afcf5cfb51bfc9be57c9120646df..5bf52e5b45bd6d3360938fa2ba3eb5dcd613a93d 100644
--- a/src/homepage.js
+++ b/src/homepage.js
@@ -1,6 +1,7 @@
 "use strict";
 
-const Articles = require("./home-page-components/articles");
+const { images_url } = require("../constants");
+const NewsArticles = require("./home-page-components/news-articles");
 const ThemeCard = require("./home-page-components/theme-card");
 
 class HomePage {
@@ -17,6 +18,18 @@ class HomePage {
                     tag: "div",
                     class: "page-header",
                     contents: [
+                        {
+                            tag: "div",
+                            class: "big-logo page-contents-center",
+                            contents: [
+                                { tag: "img", src: `${images_url}/logo_kuadrado.svg` },
+                                {
+                                    tag: "img",
+                                    class: "logo-text",
+                                    src: `${images_url}/logo_kuadrado_txt.svg`,
+                                },
+                            ],
+                        },
                         { tag: "h1", contents: "Kuadrado Software", class: "page-contents-center" },
                         {
                             tag: "p",
@@ -33,7 +46,7 @@ class HomePage {
                     class: "page-contents-center",
                     contents: [
                         { tag: "h2", contents: "Actu", class: "section-title bg-blue" },
-                        new Articles().render(),
+                        new NewsArticles().render(),
                     ],
                 },
                 {
diff --git a/src/homepage.scss b/src/homepage.scss
index 8ee0bc2554b60555ebae85bd7e81cda82603dcb3..b1a4555bcc9d94e16efa6548b3d0871d625743a6 100644
--- a/src/homepage.scss
+++ b/src/homepage.scss
@@ -3,6 +3,24 @@
     flex-direction: column;
     gap: 20px;
     margin-bottom: 60px;
+    .page-header {
+        .big-logo {
+            @include flex-center;
+            gap: 20px;
+            padding: 20px;
+            img {
+                width: 200px;
+                max-width: 100%;
+                &.logo-text {
+                    width: 300px;
+                    max-width: 100%;
+                }
+            }
+            @media screen and (max-width: $screen_s) {
+                flex-direction: column;
+            }
+        }
+    }
     .section-title {
         padding: 10px;
         margin: 0;
@@ -12,52 +30,57 @@
 
     .articles-displayer {
         margin: 0 auto 40px;
-        display: grid;
-        grid-template-columns: 50px auto 50px;
-        .prev-btn,
-        .next-btn {
-            border: none;
-            background-image: url("/assets/images/wallpaper_binary.png");
-            &.disabled {
-                pointer-events: none;
-            }
-            &.active {
-                cursor: pointer;
-                color: $medium_grey;
-                &:hover {
-                    color: $light_0;
+        .prev-next-buttons {
+            display: flex;
+            justify-content: space-between;
+            .prev-btn,
+            .next-btn {
+                border: none;
+                background: none;
+                display: flex;
+                align-items: center;
+                gap: 10px;
+                padding: 5px 0;
+                &.disabled {
+                    visibility: hidden;
+                    pointer-events: none;
+                }
+                &.active {
+                    cursor: pointer;
+                    color: $medium_grey;
+                    &:hover {
+                        color: $dark_2;
+                    }
                 }
             }
-        }
-        .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;
+            .next-btn {
+                &.active {
+                    &::after {
+                        content: " ";
+                        border-style: solid;
+                        border-width: 2px 2px 0 0;
+                        width: 8px;
+                        height: 8px;
+                        transform: rotate(45deg);
+                        @include flex-center;
+                    }
                 }
             }
-        }
-        .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;
+            .prev-btn {
+                &.active {
+                    &::before {
+                        content: " ";
+                        border-style: solid;
+                        border-width: 2px 2px 0 0;
+                        width: 8px;
+                        height: 8px;
+                        transform: rotate(-135deg);
+                        @include flex-center;
+                    }
                 }
             }
         }
+
         article {
             display: grid;
             gap: 5px 20px;
@@ -93,37 +116,11 @@
                 grid-row: 4;
                 min-height: 250px;
                 padding-bottom: 40px;
+                text-align: justify;
             }
             .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%;
-                    max-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;
@@ -142,7 +139,6 @@
             }
         }
         @media screen and (max-width: $screen_l) {
-            grid-template-columns: 40px auto 40px;
             article {
                 gap: 5px;
                 grid-template-columns: 1fr;
@@ -167,16 +163,6 @@
                 .image-carousel {
                     grid-row: 1;
                     grid-column: 1;
-                    img {
-                        max-height: 100%;
-                    }
-                    .carousel-bullets {
-                        gap: 15px;
-                        .bullet {
-                            width: 12px;
-                            height: 12px;
-                        }
-                    }
                 }
             }
         }
@@ -215,7 +201,7 @@
             .card-description {
                 background-image: url("/assets/images/wallpaper_binary.png");
                 flex: 1;
-                padding: 20px 30px 30px;
+                padding: 30px 20px;
                 p {
                     margin: 0;
                     color: $blue_3;
@@ -248,7 +234,7 @@
                 .card-description {
                     background-image: url("/assets/images/wallpaper_binary.png");
                     flex: 1;
-                    padding: 10px 10px 20px;
+                    padding: 20px 30px;
                     p {
                         margin: 0;
                         color: $blue_3;
diff --git a/src/lib/article-utils.js b/src/lib/article-utils.js
new file mode 100644
index 0000000000000000000000000000000000000000..0d68c2a85baef65b0e91f30949c2b6fc11f04142
--- /dev/null
+++ b/src/lib/article-utils.js
@@ -0,0 +1,71 @@
+"use strict";
+
+const { fetchjson, fetchtext } = require("./fetch");
+
+function getArticleBody(text) {
+    return text
+        .split(" ")
+        .map(word => {
+            if (word.includes("http://") || word.includes("https://")) {
+                const splitword = word.split("||");
+                const href = splitword[0].match(/http.+/);
+                const text = splitword.length > 1 ? splitword[1].replaceAll("_", " ") : href;
+                return word.replace(/http.*/, `<a href=${href} target="_blank">${text}</a>`);
+            } else return word;
+        })
+        .join(" ")
+        .replaceAll("\n", "<br/>");
+}
+
+function getArticleDate(date) {
+    return `${date.getDate()}-${date.getMonth() + 1}-${date.getFullYear()}`;
+}
+
+function loadArticles(dir_url) {
+    return new Promise((resolve, reject) => {
+        fetchjson(`${dir_url}/index.json`)
+            .then(json => {
+                Promise.all(
+                    json.map(async articlePath => {
+                        const art = await fetchjson(`${dir_url}/${articlePath}`);
+                        const tmpSplit = articlePath.split("/");
+                        tmpSplit.pop();
+                        const absArtPath = `${dir_url}/${tmpSplit.join("/")}`;
+                        return Object.assign(art, { path: absArtPath });
+                    })
+                )
+                    .then(articles => {
+                        populateArticles(articles)
+                            .then(completeArticles => resolve(completeArticles))
+                            .catch(e => reject(e));
+                    })
+                    .catch(e => reject(e));
+            })
+            .catch(e => console.log(e));
+    });
+}
+
+function populateArticles(articles) {
+    return new Promise((resolve, reject) => {
+        Promise.all(
+            articles.map(async article => {
+                if (article.body.indexOf("<file>") !== -1) {
+                    const txtPath = article.body.replace("<file>", "");
+                    const textValue = await fetchtext(`${article.path}/${txtPath}`);
+                    article.body = textValue;
+                    article.date = article.date ? new Date(article.date) : undefined;
+                }
+                return article;
+            })
+        )
+            .then(completeArticles => resolve(completeArticles.sort((a, b) => a.date - b.date)))
+            .catch(e => reject(e));
+    });
+}
+
+module.exports = {
+    loadArticles,
+    getArticleBody,
+    getArticleDate,
+    populateArticles,
+};
diff --git a/src/pages/games/components/game-article.js b/src/pages/games/components/game-article.js
new file mode 100644
index 0000000000000000000000000000000000000000..12401599e47e332948016da93f589ca471bb19f8
--- /dev/null
+++ b/src/pages/games/components/game-article.js
@@ -0,0 +1,98 @@
+"use strict";
+
+const ImageCarousel = require("../../../generic-components/image-carousel");
+const { getArticleBody } = require("../../../lib/article-utils");
+
+class TeamMember {
+    constructor(props) {
+        this.props = props;
+    }
+
+    render() {
+        const { title, subtitle, body, images, path } = this.props;
+        return {
+            tag: "div",
+            class: "team-member",
+            contents: [
+                {
+                    tag: "div",
+                    class: "team-member-img",
+                    contents: [{ tag: "img", src: images.map(im => `${path}/images/${im}`)[0] }],
+                },
+                {
+                    tag: "h3",
+                    class: "team-member-title",
+                    contents: title,
+                },
+                {
+                    tag: "strong",
+                    class: "team-member-subtitle",
+                    contents: subtitle,
+                },
+                {
+                    tag: "p",
+                    class: "team-member-body",
+                    contents: getArticleBody(body),
+                },
+            ],
+        };
+    }
+}
+
+class GameArticle {
+    constructor(props) {
+        this.props = props;
+    }
+
+    render() {
+        const { title, tags, body, subtitle, images, path, team_subarticles } = this.props;
+        return {
+            tag: "article",
+            class: "game-article",
+            contents: [
+                {
+                    tag: "h2",
+                    class: "game-title",
+                    contents: title,
+                },
+                {
+                    tag: "div",
+                    class: "game-tags",
+                    contents: tags.map(tag => {
+                        return { tag: "span", contents: tag };
+                    }),
+                },
+                {
+                    tag: "h3",
+                    class: "game-subtitle",
+                    contents: subtitle,
+                },
+                {
+                    tag: "div",
+                    class: "game-description",
+                    contents: getArticleBody(body),
+                },
+                new ImageCarousel({ images: images.map(img => `${path}/images/${img}`) }).render(),
+                {
+                    tag: "div",
+                    class: "game-team",
+                    contents: [
+                        {
+                            tag: "h2",
+                            contents: "L'équipe",
+                        },
+                        {
+                            tag: "div",
+                            class: "team-members",
+                            contents: team_subarticles.map(tsa =>
+                                new TeamMember({ ...tsa }).render()
+                            ),
+                        },
+                    ],
+                },
+            ],
+        };
+    }
+}
+
+module.exports = GameArticle;
diff --git a/src/pages/games/components/game-articles.js b/src/pages/games/components/game-articles.js
new file mode 100644
index 0000000000000000000000000000000000000000..6f7fb8541a6a899e83e07738c9c81b8b5de96c23
--- /dev/null
+++ b/src/pages/games/components/game-articles.js
@@ -0,0 +1,66 @@
+"use strict";
+
+const { game_articles_url } = require("../../../../constants");
+const { loadArticles, populateArticles } = require("../../../lib/article-utils");
+const objectHtmlRenderer = require("../../../lib/object-html-renderer");
+const GameArticle = require("./game-article");
+
+class GameArticles {
+    constructor(props) {
+        this.props = props;
+        this.state = {
+            articles: [],
+        };
+        this.id = performance.now();
+        this.loadArticles();
+    }
+
+    loadArticles() {
+        loadArticles(game_articles_url)
+            .then(articles => {
+                Promise.all(
+                    articles.map(async a => {
+                        if (a.team_subarticles) {
+                            a.team_subarticles = await populateArticles(
+                                a.team_subarticles.map(sa => Object.assign(sa, { path: a.path }))
+                            );
+                        }
+                        return a;
+                    })
+                ).then(completeArticles => {
+                    this.state.articles = completeArticles;
+                    this.refresh();
+                });
+            })
+            .catch(e => console.log(e));
+    }
+
+    renderPlaceholder() {
+        return {
+            tag: "article",
+            class: "placeholder",
+            contents: [{ tag: "div" }, { tag: "div" }],
+        };
+    }
+
+    refresh() {
+        objectHtmlRenderer.subRender(this.render(), document.getElementById(this.id), {
+            mode: "replace",
+        });
+    }
+
+    render() {
+        const { articles } = this.state;
+        return {
+            tag: "section",
+            class: "game-articles page-contents-center",
+            id: this.id,
+            contents:
+                articles.length > 0
+                    ? articles.map(article => new GameArticle({ ...article }).render())
+                    : [this.renderPlaceholder()],
+        };
+    }
+}
+
+module.exports = GameArticles;
diff --git a/src/pages/games/games.js b/src/pages/games/games.js
index c39b9d68572130f79b4d59860bc8d80fc0bf49fc..1e83cc0b8edf5bc1fae7094eee75454ae15b5fb0 100644
--- a/src/pages/games/games.js
+++ b/src/pages/games/games.js
@@ -1,5 +1,7 @@
 "use strict";
 
+const GameArticles = require("./components/game-articles");
+
 class GamesPage {
     constructor(args) {
         Object.assign(this, args);
@@ -8,14 +10,22 @@ class GamesPage {
     render() {
         return {
             tag: "div",
+            id:"games-page",
             contents: [
                 {
                     tag: "div",
                     class: "page-header",
                     contents: [
-                        { tag: "h1", contents: "Jeux", class: "page-contents-center" }
+                        { tag: "h1", contents: "Jeux", class: "page-contents-center" },
+                        {
+                            tag: "p",
+                            class: "page-contents-center",
+                            contents: `Créer des jeux vidéos c'est cœur de ce qui nous passionne.
+                            <br/>Retrouvez ici nos créations, à jouer en ligne ou à télécharger, et découvrez nos projets en cours.`,
+                        },
                     ],
                 },
+                new GameArticles().render(),
             ],
         };
     }
diff --git a/src/pages/games/games.scss b/src/pages/games/games.scss
new file mode 100644
index 0000000000000000000000000000000000000000..ce231c7004a6b2022fc9164f477351a5b01d7e48
--- /dev/null
+++ b/src/pages/games/games.scss
@@ -0,0 +1,137 @@
+#games-page {
+    .game-articles {
+        article {
+            display: grid;
+            grid-template-columns: 0.7fr 1fr;
+            gap: 0 20px;
+            margin: 20px;
+            &.game-article {
+                grid-template-rows: repeat(6, auto);
+                background-color: $dark_2;
+                *:not(a) {
+                    color: $light_0;
+                }
+                .game-title {
+                    grid-column: 1 / span 2;
+                    background-color: $light_0;
+                    margin: 0;
+                    padding: 30px 20px;
+                    color: $medium_grey;
+                    font-size: 35px;
+                    font-style: italic;
+                }
+                .game-tags {
+                    grid-column: 1;
+                    display: flex;
+                    gap: 10px;
+                    flex-wrap: wrap;
+                    margin: 10px 20px;
+                    span {
+                        font-size: 12px;
+                        padding: 6px;
+                        background-color: $yellow_2;
+                        color: $medium_grey;
+                        border-radius: 5px;
+                        font-weight: 600;
+                    }
+                }
+                .game-subtitle {
+                    grid-column: 1;
+                    margin: 10px 20px 30px;
+                }
+                .game-description {
+                    grid-column: 1;
+                    text-align: justify;
+                    margin: 10px 20px 30px;
+                }
+
+                .image-carousel {
+                    grid-column: 2;
+                    grid-row: 2 / span 4;
+                    height: 400px;
+                }
+                .game-team {
+                    grid-column: 1 / span 2;
+                    h2 {
+                        background-color: $light_0;
+                        color: $medium_grey;
+                        padding: 10px 20px;
+                        font-style: italic;
+                        font-size: 20px;
+                        margin: 0;
+                    }
+                    .team-members {
+                        display: flex;
+                        flex-direction: column;
+                        gap: 30px;
+                        .team-member {
+                            display: grid;
+                            grid-template-columns: 150px 1fr;
+                            grid-template-rows: auto auto 1fr;
+                            .team-member-img {
+                                grid-row: 1 / span 3;
+                                overflow: hidden;
+                                img {
+                                    image-rendering: crisp-edges;
+                                    image-rendering: -moz-crisp-edges;
+                                    image-rendering: pixelated;
+                                    width: 100%;
+                                }
+                            }
+                            .team-member-title {
+                                margin: 10px 10px 5px;
+                            }
+                            .team-member-subtitle {
+                                margin: 0 10px;
+                                font-size: 14px;
+                                color: $light_1;
+                                font-style: italic;
+                            }
+                            .team-member-body {
+                                margin: 20px 10px 20px 30px;
+                                text-align: justify;
+                            }
+                        }
+                    }
+                }
+            }
+            &.placeholder {
+                * {
+                    background-color: $light_0;
+                }
+                height: 400px;
+            }
+            @media screen and (max-width: $screen_l) {
+                grid-template-columns: 1fr;
+                &.game-article {
+                    grid-template-rows: repeat(5, auto);
+                    .game-title {
+                        grid-column: 1;
+                        padding: 20px;
+                        font-size: 25px;
+                    }
+
+                    .image-carousel {
+                        grid-column: 1;
+                        grid-row: 2;
+                    }
+                    .game-team {
+                        grid-column: 1;
+                        .team-members {
+                            .team-member {
+                                grid-template-columns: 70px 1fr;
+                                .team-member-img {
+                                    grid-row: 1 / span 2;
+                                    margin: 10px;
+                                }
+                                .team-member-body {
+                                    grid-column: 1 / span 2;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/style.scss b/src/style.scss
index 40794a19af717b926dbb88ad10d387a4c798e124..787e57edea7320e547e3c6409666b8c4dd0cdfcd 100644
--- a/src/style.scss
+++ b/src/style.scss
@@ -40,6 +40,61 @@ main {
     flex-direction: column;
     align-items: center;
     min-height: 100vh;
+
+    .warning-banner {
+        background: url("/assets/images/wallpaper_warning.svg");
+        width: 100%;
+        height: 40px;
+        padding: 20px 10%;
+        @include flex-center;
+        strong {
+            font-size: 18px;
+            color: $blue_1;
+        }
+    }
+
+    .image-carousel {
+        overflow: hidden;
+        @include flex-center;
+        background-color: black;
+        position: relative;
+        img {
+            position: absolute;
+            max-width: 100%;
+            max-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;
+                }
+            }
+        }
+        @media screen and (max-width: $screen_l) {
+            img {
+                max-height: 100%;
+            }
+            .carousel-bullets {
+                gap: 15px;
+                .bullet {
+                    width: 12px;
+                    height: 12px;
+                }
+            }
+        }
+    }
+
     header {
         width: 100%;
         nav {
@@ -97,7 +152,7 @@ main {
                     &.active {
                         a {
                             color: $dark_2;
-                            border-bottom: 1px solid;
+                            border-bottom: 2px solid;
                         }
                     }
                     &:hover {
@@ -194,16 +249,18 @@ main {
         }
         @import "./homepage.scss";
         @import "./pages/education/education.scss";
+        @import "./pages/games/games.scss";
     }
     footer {
         @include flex-center-col;
         width: 100%;
         background-image: url("/assets/images/wallpaper_binary.png");
-        padding: 20px;
+        padding: 40px 20px;
         gap: 20px;
         font-size: 12px;
         span {
             color: $light_1;
+            text-align: center;
         }
         .logo {
             @include flex-center;
diff --git a/src/template/template.js b/src/template/template.js
index 74a5dbcffb09cf1b8cd32deac39ebd5cf8e78d37..ab81e0b593b094345ef51561a5f0126872fb1899 100644
--- a/src/template/template.js
+++ b/src/template/template.js
@@ -1,5 +1,6 @@
 "use strict";
 
+const { in_construction } = require("../../config");
 const { images_url } = require("../../constants");
 const NavBar = require("./components/navbar");
 
@@ -15,8 +16,19 @@ class Template {
                     tag: "header",
                     contents: [new NavBar().render()],
                 },
+                in_construction && {
+                    tag: "section",
+                    class: "warning-banner",
+                    contents: [
+                        {
+                            tag: "strong",
+                            class: "page-contents-center",
+                            contents: "Site en construction ...",
+                        },
+                    ],
+                },
                 {
-                    tag: "div",
+                    tag: "section",
                     id: "page-container",
                     contents: [this.props.page.render()],
                 },
@@ -33,14 +45,15 @@ class Template {
                                 },
                                 {
                                     tag: "img",
-                                    class:"text-logo",
+                                    class: "text-logo",
                                     src: `${images_url}/logo_kuadrado_txt.svg`,
                                 },
                             ],
                         },
                         {
-                            tag:"span",
-                            contents: "Toutes les images du site ont été réalisées par nos soins et peuvent être réutilisées pour un usage personnel."
+                            tag: "span",
+                            contents:
+                                "Toutes les images du site ont été réalisées par nos soins et peuvent être réutilisées pour un usage personnel.",
                         },
                         {
                             tag: "a",
diff --git a/src/theme.scss b/src/theme.scss
index e7ae8e2f43eb36d7f81e5b80c66e2d8bc265d445..54e0053f7128de9facf8a14a397e7ef68577236b 100644
--- a/src/theme.scss
+++ b/src/theme.scss
@@ -36,7 +36,7 @@ $page_contents_center_width: 1300px;
 
 @mixin page-header {
     background-image: url("/assets/images/wallpaper_binary.png");
-    padding: 10px 0;
+    padding: 50px 0;
     h1 {
         padding: 15px 40px 0;
         font-size: 25px;
@@ -57,7 +57,8 @@ $page_contents_center_width: 1300px;
             padding: 15px 20px 0;
         }
         p {
-            padding: 15px;
+            padding: 20px 20px 30px 40px;
+            text-align: justify;
         }
     }
 }