From d7d453f7333def28007b94b9c9d872f89224fc91 Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Thu, 31 Mar 2022 14:25:12 +0200
Subject: chore: add a button component

---
 __tests__/jest/components/Copyright.test.tsx | 1 -
 1 file changed, 1 deletion(-)

(limited to '__tests__/jest/components/Copyright.test.tsx')

diff --git a/__tests__/jest/components/Copyright.test.tsx b/__tests__/jest/components/Copyright.test.tsx
index 5f6f287..08beb50 100644
--- a/__tests__/jest/components/Copyright.test.tsx
+++ b/__tests__/jest/components/Copyright.test.tsx
@@ -1,6 +1,5 @@
 import Copyright from '@components/Copyright/Copyright';
 import { render, screen } from '@test-utils';
-import '../__mocks__/matchMedia.mock';
 
 describe('Copyright', () => {
   it('renders the Copyright component', () => {
-- 
cgit v1.2.3


From 7e16f500cb7bc0cfd8bafbf6bb1555704f771231 Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Fri, 29 Apr 2022 12:13:34 +0200
Subject: chore: remove old pages, components, helpers and types

Since I'm using new components, I will also rewrite the GraphQL queries
so it is easier to start from scratch.
---
 __tests__/jest/components/Branding.test.tsx        |  24 -
 __tests__/jest/components/Copyright.test.tsx       |  13 -
 __tests__/jest/components/Header.test.tsx          |  12 -
 src/components/Branding/Branding.module.scss       | 169 -------
 src/components/Branding/Branding.tsx               | 107 -----
 src/components/Branding/Logo/Logo.module.scss      |  23 -
 src/components/Branding/Logo/Logo.tsx              |  32 --
 src/components/Breadcrumb/Breadcrumb.module.scss   |  29 --
 src/components/Breadcrumb/Breadcrumb.tsx           | 155 ------
 src/components/Buttons/Button/Button.tsx           |  35 --
 .../Buttons/ButtonHelp/ButtonHelp.module.scss      |  52 --
 src/components/Buttons/ButtonHelp/ButtonHelp.tsx   |  42 --
 src/components/Buttons/ButtonLink/ButtonLink.tsx   |  30 --
 .../Buttons/ButtonSubmit/ButtonSubmit.tsx          |  22 -
 .../Buttons/ButtonToolbar/ButtonToolbar.tsx        |  72 ---
 src/components/Buttons/Buttons.module.scss         | 289 -----------
 src/components/Buttons/index.tsx                   |   7 -
 src/components/Comment/Comment.module.scss         |  99 ----
 src/components/Comment/Comment.tsx                 | 200 --------
 src/components/CommentForm/CommentForm.module.scss |  25 -
 src/components/CommentForm/CommentForm.tsx         | 240 ---------
 .../CommentsList/CommentsList.module.scss          |  14 -
 src/components/CommentsList/CommentsList.tsx       |  69 ---
 src/components/ContactForm/ContactForm.module.scss |  21 -
 src/components/ContactForm/ContactForm.tsx         | 180 -------
 src/components/Copyright/Copyright.module.scss     |  33 --
 src/components/Copyright/Copyright.tsx             |  17 -
 src/components/Footer/Footer.module.scss           |  90 ----
 src/components/Footer/Footer.tsx                   |  54 ---
 src/components/FooterNav/FooterNav.module.scss     |  20 -
 src/components/FooterNav/FooterNav.tsx             |  45 --
 .../FormElements/Field/Field.module.scss           |  53 --
 src/components/FormElements/Field/Field.tsx        | 106 ----
 src/components/FormElements/Form/Form.module.scss  |  37 --
 src/components/FormElements/Form/Form.tsx          |  27 --
 .../FormElements/FormItem/FormItem.module.scss     |   4 -
 src/components/FormElements/FormItem/FormItem.tsx  |   7 -
 .../FormElements/Label/Label.module.scss           |  22 -
 src/components/FormElements/Label/Label.tsx        |  24 -
 .../FormElements/Toggle/Toggle.module.scss         |  75 ---
 src/components/FormElements/Toggle/Toggle.tsx      |  46 --
 src/components/FormElements/index.tsx              |   7 -
 src/components/Header/Header.module.scss           |  22 -
 src/components/Header/Header.tsx                   |  16 -
 src/components/Icons/Arrow/Arrow.module.scss       |   7 -
 src/components/Icons/Arrow/Arrow.tsx               |  81 ----
 src/components/Icons/Blog/Blog.module.scss         |  23 -
 src/components/Icons/Blog/Blog.tsx                 |  62 ---
 src/components/Icons/CV/CV.module.scss             |  54 ---
 src/components/Icons/CV/CV.tsx                     |  58 ---
 src/components/Icons/Close/Close.module.scss       |  13 -
 src/components/Icons/Close/Close.tsx               |  22 -
 src/components/Icons/Cog/Cog.module.scss           |  10 -
 src/components/Icons/Cog/Cog.tsx                   |  16 -
 src/components/Icons/Contact/Contact.module.scss   |  29 --
 src/components/Icons/Contact/Contact.tsx           |  54 ---
 .../Icons/Copyright/Copyright.module.scss          |   7 -
 src/components/Icons/Copyright/Copyright.tsx       |  23 -
 .../Icons/Hamburger/Hamburger.module.scss          |  56 ---
 src/components/Icons/Hamburger/Hamburger.tsx       |  10 -
 src/components/Icons/Home/Home.module.scss         |  42 --
 src/components/Icons/Home/Home.tsx                 |  42 --
 src/components/Icons/Moon/Moon.module.scss         |   8 -
 src/components/Icons/Moon/Moon.tsx                 |  25 -
 src/components/Icons/Projects/Projects.module.scss |  40 --
 src/components/Icons/Projects/Projects.tsx         |  66 ---
 src/components/Icons/Search/Search.module.scss     |  31 --
 src/components/Icons/Search/Search.tsx             |  30 --
 src/components/Icons/Sun/Sun.module.scss           |   8 -
 src/components/Icons/Sun/Sun.tsx                   |  25 -
 src/components/Icons/index.tsx                     |  29 --
 src/components/Layouts/Layout.module.scss          |  20 -
 src/components/Layouts/Layout.tsx                  | 155 ------
 src/components/MDX/CodeBlock/CodeBlock.tsx         | 115 -----
 src/components/MDX/Gallery/Gallery.module.scss     |  32 --
 src/components/MDX/Gallery/Gallery.tsx             |  22 -
 src/components/MDX/Link/Link.tsx                   |  23 -
 .../ResponsiveImage/ResponsiveImage.module.scss    |  50 --
 .../MDX/ResponsiveImage/ResponsiveImage.tsx        |  40 --
 src/components/MDX/index.tsx                       |   6 -
 src/components/Main/Main.module.scss               |   7 -
 src/components/Main/Main.tsx                       |  12 -
 src/components/MainNav/MainNav.module.scss         | 242 ----------
 src/components/MainNav/MainNav.tsx                 | 155 ------
 src/components/MetaItems/Author/Author.tsx         |  21 -
 .../MetaItems/CommentsCount/CommentsCount.tsx      |  43 --
 src/components/MetaItems/Dates/Dates.tsx           |  58 ---
 .../MetaItems/MetaItem/MetaItem.module.scss        |  18 -
 src/components/MetaItems/MetaItem/MetaItem.tsx     |  36 --
 src/components/MetaItems/PostsCount/PostsCount.tsx |  29 --
 .../MetaItems/ReadingTime/ReadingTime.tsx          |  59 ---
 src/components/MetaItems/Thematics/Thematics.tsx   |  43 --
 src/components/MetaItems/Topics/Topics.tsx         |  37 --
 src/components/MetaItems/Website/Website.tsx       |  21 -
 src/components/MetaItems/index.tsx                 |  21 -
 src/components/Notice/Notice.module.scss           |  28 --
 src/components/Notice/Notice.tsx                   |  21 -
 src/components/Pagination/Pagination.module.scss   |  92 ----
 src/components/Pagination/Pagination.tsx           | 136 ------
 .../PaginationCursor/PaginationCursor.module.scss  |  43 --
 .../PaginationCursor/PaginationCursor.tsx          |  43 --
 src/components/PostFooter/PostFooter.module.scss   |  18 -
 src/components/PostFooter/PostFooter.tsx           |  53 --
 src/components/PostHeader/PostHeader.module.scss   |  83 ----
 src/components/PostHeader/PostHeader.tsx           |  57 ---
 src/components/PostMeta/PostMeta.module.scss       |  31 --
 src/components/PostMeta/PostMeta.tsx               |  67 ---
 src/components/PostPreview/PostPreview.module.scss | 105 ----
 src/components/PostPreview/PostPreview.tsx         | 120 -----
 src/components/PostsList/PostsList.module.scss     |  51 --
 src/components/PostsList/PostsList.tsx             | 110 -----
 .../ProjectPreview/ProjectPreview.module.scss      |  98 ----
 src/components/ProjectPreview/ProjectPreview.tsx   |  73 ---
 .../ProjectSummary/ProjectSummary.module.scss      |  73 ---
 src/components/ProjectSummary/ProjectSummary.tsx   | 178 -------
 .../ProjectsList/ProjectsList.module.scss          |  25 -
 src/components/ProjectsList/ProjectsList.tsx       |  21 -
 src/components/SearchForm/SearchForm.module.scss   |   6 -
 src/components/SearchForm/SearchForm.tsx           |  70 ---
 .../Settings/AckeeSelect/AckeeSelect.module.scss   |   6 -
 .../Settings/AckeeSelect/AckeeSelect.tsx           |  96 ----
 .../Settings/PrismThemeToggle/PrismThemeToggle.tsx |  50 --
 .../Settings/ReduceMotion/ReduceMotion.tsx         |  48 --
 src/components/Settings/Settings.module.scss       |  17 -
 src/components/Settings/Settings.tsx               |  30 --
 .../Settings/ThemeToggle/ThemeToggle.tsx           |  41 --
 src/components/Sidebar/Sidebar.module.scss         |  43 --
 src/components/Sidebar/Sidebar.tsx                 |  40 --
 src/components/Spinner/Spinner.module.scss         |  48 --
 src/components/Spinner/Spinner.tsx                 |  24 -
 src/components/Toolbar/Toolbar.module.scss         | 114 -----
 src/components/Toolbar/Toolbar.tsx                 | 162 -------
 src/components/Tooltip/Tooltip.module.scss         | 120 -----
 src/components/Tooltip/Tooltip.tsx                 |  59 ---
 .../ExpandableWidget/ExpandableWidget.module.scss  | 146 ------
 .../ExpandableWidget/ExpandableWidget.tsx          |  61 ---
 src/components/WidgetParts/List/List.module.scss   |  49 --
 src/components/WidgetParts/List/List.tsx           |   7 -
 .../OrderedList/OrderedList.module.scss            |  66 ---
 .../WidgetParts/OrderedList/OrderedList.tsx        |   7 -
 src/components/WidgetParts/index.tsx               |   5 -
 .../Widgets/CVPreview/CVPreview.module.scss        |   6 -
 src/components/Widgets/CVPreview/CVPreview.tsx     |  45 --
 .../Widgets/RecentPosts/RecentPosts.module.scss    | 109 -----
 src/components/Widgets/RecentPosts/RecentPosts.tsx |  78 ---
 .../Widgets/RelatedThematics/RelatedThematics.tsx  |  41 --
 .../Widgets/RelatedTopics/RelatedTopics.tsx        |  41 --
 src/components/Widgets/Sharing/Sharing.module.scss | 193 --------
 src/components/Widgets/Sharing/Sharing.tsx         | 238 ---------
 .../Widgets/SocialMedia/SocialMedia.module.scss    |  59 ---
 src/components/Widgets/SocialMedia/SocialMedia.tsx | 113 -----
 .../Widgets/ThematicsList/ThematicsList.tsx        |  76 ---
 src/components/Widgets/ToC/ToC.tsx                 |  55 ---
 src/components/Widgets/TopicsList/TopicsList.tsx   |  76 ---
 src/components/Widgets/index.tsx                   |  21 -
 src/pages/404.tsx                                  |  85 ----
 src/pages/_app.tsx                                 |   9 +-
 src/pages/article/[slug].tsx                       | 291 -----------
 src/pages/blog/index.tsx                           | 269 -----------
 src/pages/blog/page/[id].tsx                       | 205 --------
 src/pages/contact.tsx                              | 151 ------
 src/pages/cv.tsx                                   | 181 -------
 src/pages/index.tsx                                | 241 ----------
 src/pages/mentions-legales.tsx                     | 150 ------
 src/pages/projet/[slug].tsx                        | 186 -------
 src/pages/projets.tsx                              | 128 -----
 src/pages/recherche/index.tsx                      | 213 --------
 src/pages/sujet/[slug].tsx                         | 224 ---------
 src/pages/thematique/[slug].tsx                    | 214 ---------
 src/services/graphql/api.ts                        |  25 -
 src/services/graphql/mutations.ts                  |  82 ----
 src/services/graphql/queries.ts                    | 535 ---------------------
 src/ts/types/app.ts                                | 160 ------
 src/ts/types/articles.ts                           | 102 ----
 src/ts/types/blog.ts                               |  41 --
 src/ts/types/comments.ts                           |  61 ---
 src/ts/types/contact.ts                            |  19 -
 src/ts/types/cover.ts                              |   9 -
 src/ts/types/nav.ts                                |   5 -
 src/ts/types/prism.ts                              |  51 --
 src/ts/types/repos.ts                              |   7 -
 src/ts/types/seo.ts                                |   6 -
 src/ts/types/taxonomies.ts                         | 114 -----
 src/utils/helpers/format.ts                        | 332 -------------
 src/utils/helpers/i18n.ts                          |   2 +-
 src/utils/helpers/prism.ts                         |  34 --
 src/utils/helpers/projects.ts                      |  86 ----
 src/utils/helpers/sort.ts                          |  21 -
 src/utils/hooks/useGithubApi.tsx                   |  23 -
 src/utils/hooks/useHeadingsTree.tsx                | 104 ----
 src/utils/providers/ackee.tsx                      |   3 +-
 src/utils/providers/prism-theme.tsx                |   2 +
 192 files changed, 9 insertions(+), 13156 deletions(-)
 delete mode 100644 __tests__/jest/components/Branding.test.tsx
 delete mode 100644 __tests__/jest/components/Copyright.test.tsx
 delete mode 100644 __tests__/jest/components/Header.test.tsx
 delete mode 100644 src/components/Branding/Branding.module.scss
 delete mode 100644 src/components/Branding/Branding.tsx
 delete mode 100644 src/components/Branding/Logo/Logo.module.scss
 delete mode 100644 src/components/Branding/Logo/Logo.tsx
 delete mode 100644 src/components/Breadcrumb/Breadcrumb.module.scss
 delete mode 100644 src/components/Breadcrumb/Breadcrumb.tsx
 delete mode 100644 src/components/Buttons/Button/Button.tsx
 delete mode 100644 src/components/Buttons/ButtonHelp/ButtonHelp.module.scss
 delete mode 100644 src/components/Buttons/ButtonHelp/ButtonHelp.tsx
 delete mode 100644 src/components/Buttons/ButtonLink/ButtonLink.tsx
 delete mode 100644 src/components/Buttons/ButtonSubmit/ButtonSubmit.tsx
 delete mode 100644 src/components/Buttons/ButtonToolbar/ButtonToolbar.tsx
 delete mode 100644 src/components/Buttons/Buttons.module.scss
 delete mode 100644 src/components/Buttons/index.tsx
 delete mode 100644 src/components/Comment/Comment.module.scss
 delete mode 100644 src/components/Comment/Comment.tsx
 delete mode 100644 src/components/CommentForm/CommentForm.module.scss
 delete mode 100644 src/components/CommentForm/CommentForm.tsx
 delete mode 100644 src/components/CommentsList/CommentsList.module.scss
 delete mode 100644 src/components/CommentsList/CommentsList.tsx
 delete mode 100644 src/components/ContactForm/ContactForm.module.scss
 delete mode 100644 src/components/ContactForm/ContactForm.tsx
 delete mode 100644 src/components/Copyright/Copyright.module.scss
 delete mode 100644 src/components/Copyright/Copyright.tsx
 delete mode 100644 src/components/Footer/Footer.module.scss
 delete mode 100644 src/components/Footer/Footer.tsx
 delete mode 100644 src/components/FooterNav/FooterNav.module.scss
 delete mode 100644 src/components/FooterNav/FooterNav.tsx
 delete mode 100644 src/components/FormElements/Field/Field.module.scss
 delete mode 100644 src/components/FormElements/Field/Field.tsx
 delete mode 100644 src/components/FormElements/Form/Form.module.scss
 delete mode 100644 src/components/FormElements/Form/Form.tsx
 delete mode 100644 src/components/FormElements/FormItem/FormItem.module.scss
 delete mode 100644 src/components/FormElements/FormItem/FormItem.tsx
 delete mode 100644 src/components/FormElements/Label/Label.module.scss
 delete mode 100644 src/components/FormElements/Label/Label.tsx
 delete mode 100644 src/components/FormElements/Toggle/Toggle.module.scss
 delete mode 100644 src/components/FormElements/Toggle/Toggle.tsx
 delete mode 100644 src/components/FormElements/index.tsx
 delete mode 100644 src/components/Header/Header.module.scss
 delete mode 100644 src/components/Header/Header.tsx
 delete mode 100644 src/components/Icons/Arrow/Arrow.module.scss
 delete mode 100644 src/components/Icons/Arrow/Arrow.tsx
 delete mode 100644 src/components/Icons/Blog/Blog.module.scss
 delete mode 100644 src/components/Icons/Blog/Blog.tsx
 delete mode 100644 src/components/Icons/CV/CV.module.scss
 delete mode 100644 src/components/Icons/CV/CV.tsx
 delete mode 100644 src/components/Icons/Close/Close.module.scss
 delete mode 100644 src/components/Icons/Close/Close.tsx
 delete mode 100644 src/components/Icons/Cog/Cog.module.scss
 delete mode 100644 src/components/Icons/Cog/Cog.tsx
 delete mode 100644 src/components/Icons/Contact/Contact.module.scss
 delete mode 100644 src/components/Icons/Contact/Contact.tsx
 delete mode 100644 src/components/Icons/Copyright/Copyright.module.scss
 delete mode 100644 src/components/Icons/Copyright/Copyright.tsx
 delete mode 100644 src/components/Icons/Hamburger/Hamburger.module.scss
 delete mode 100644 src/components/Icons/Hamburger/Hamburger.tsx
 delete mode 100644 src/components/Icons/Home/Home.module.scss
 delete mode 100644 src/components/Icons/Home/Home.tsx
 delete mode 100644 src/components/Icons/Moon/Moon.module.scss
 delete mode 100644 src/components/Icons/Moon/Moon.tsx
 delete mode 100644 src/components/Icons/Projects/Projects.module.scss
 delete mode 100644 src/components/Icons/Projects/Projects.tsx
 delete mode 100644 src/components/Icons/Search/Search.module.scss
 delete mode 100644 src/components/Icons/Search/Search.tsx
 delete mode 100644 src/components/Icons/Sun/Sun.module.scss
 delete mode 100644 src/components/Icons/Sun/Sun.tsx
 delete mode 100644 src/components/Icons/index.tsx
 delete mode 100644 src/components/Layouts/Layout.module.scss
 delete mode 100644 src/components/Layouts/Layout.tsx
 delete mode 100644 src/components/MDX/CodeBlock/CodeBlock.tsx
 delete mode 100644 src/components/MDX/Gallery/Gallery.module.scss
 delete mode 100644 src/components/MDX/Gallery/Gallery.tsx
 delete mode 100644 src/components/MDX/Link/Link.tsx
 delete mode 100644 src/components/MDX/ResponsiveImage/ResponsiveImage.module.scss
 delete mode 100644 src/components/MDX/ResponsiveImage/ResponsiveImage.tsx
 delete mode 100644 src/components/MDX/index.tsx
 delete mode 100644 src/components/Main/Main.module.scss
 delete mode 100644 src/components/Main/Main.tsx
 delete mode 100644 src/components/MainNav/MainNav.module.scss
 delete mode 100644 src/components/MainNav/MainNav.tsx
 delete mode 100644 src/components/MetaItems/Author/Author.tsx
 delete mode 100644 src/components/MetaItems/CommentsCount/CommentsCount.tsx
 delete mode 100644 src/components/MetaItems/Dates/Dates.tsx
 delete mode 100644 src/components/MetaItems/MetaItem/MetaItem.module.scss
 delete mode 100644 src/components/MetaItems/MetaItem/MetaItem.tsx
 delete mode 100644 src/components/MetaItems/PostsCount/PostsCount.tsx
 delete mode 100644 src/components/MetaItems/ReadingTime/ReadingTime.tsx
 delete mode 100644 src/components/MetaItems/Thematics/Thematics.tsx
 delete mode 100644 src/components/MetaItems/Topics/Topics.tsx
 delete mode 100644 src/components/MetaItems/Website/Website.tsx
 delete mode 100644 src/components/MetaItems/index.tsx
 delete mode 100644 src/components/Notice/Notice.module.scss
 delete mode 100644 src/components/Notice/Notice.tsx
 delete mode 100644 src/components/Pagination/Pagination.module.scss
 delete mode 100644 src/components/Pagination/Pagination.tsx
 delete mode 100644 src/components/PaginationCursor/PaginationCursor.module.scss
 delete mode 100644 src/components/PaginationCursor/PaginationCursor.tsx
 delete mode 100644 src/components/PostFooter/PostFooter.module.scss
 delete mode 100644 src/components/PostFooter/PostFooter.tsx
 delete mode 100644 src/components/PostHeader/PostHeader.module.scss
 delete mode 100644 src/components/PostHeader/PostHeader.tsx
 delete mode 100644 src/components/PostMeta/PostMeta.module.scss
 delete mode 100644 src/components/PostMeta/PostMeta.tsx
 delete mode 100644 src/components/PostPreview/PostPreview.module.scss
 delete mode 100644 src/components/PostPreview/PostPreview.tsx
 delete mode 100644 src/components/PostsList/PostsList.module.scss
 delete mode 100644 src/components/PostsList/PostsList.tsx
 delete mode 100644 src/components/ProjectPreview/ProjectPreview.module.scss
 delete mode 100644 src/components/ProjectPreview/ProjectPreview.tsx
 delete mode 100644 src/components/ProjectSummary/ProjectSummary.module.scss
 delete mode 100644 src/components/ProjectSummary/ProjectSummary.tsx
 delete mode 100644 src/components/ProjectsList/ProjectsList.module.scss
 delete mode 100644 src/components/ProjectsList/ProjectsList.tsx
 delete mode 100644 src/components/SearchForm/SearchForm.module.scss
 delete mode 100644 src/components/SearchForm/SearchForm.tsx
 delete mode 100644 src/components/Settings/AckeeSelect/AckeeSelect.module.scss
 delete mode 100644 src/components/Settings/AckeeSelect/AckeeSelect.tsx
 delete mode 100644 src/components/Settings/PrismThemeToggle/PrismThemeToggle.tsx
 delete mode 100644 src/components/Settings/ReduceMotion/ReduceMotion.tsx
 delete mode 100644 src/components/Settings/Settings.module.scss
 delete mode 100644 src/components/Settings/Settings.tsx
 delete mode 100644 src/components/Settings/ThemeToggle/ThemeToggle.tsx
 delete mode 100644 src/components/Sidebar/Sidebar.module.scss
 delete mode 100644 src/components/Sidebar/Sidebar.tsx
 delete mode 100644 src/components/Spinner/Spinner.module.scss
 delete mode 100644 src/components/Spinner/Spinner.tsx
 delete mode 100644 src/components/Toolbar/Toolbar.module.scss
 delete mode 100644 src/components/Toolbar/Toolbar.tsx
 delete mode 100644 src/components/Tooltip/Tooltip.module.scss
 delete mode 100644 src/components/Tooltip/Tooltip.tsx
 delete mode 100644 src/components/WidgetParts/ExpandableWidget/ExpandableWidget.module.scss
 delete mode 100644 src/components/WidgetParts/ExpandableWidget/ExpandableWidget.tsx
 delete mode 100644 src/components/WidgetParts/List/List.module.scss
 delete mode 100644 src/components/WidgetParts/List/List.tsx
 delete mode 100644 src/components/WidgetParts/OrderedList/OrderedList.module.scss
 delete mode 100644 src/components/WidgetParts/OrderedList/OrderedList.tsx
 delete mode 100644 src/components/WidgetParts/index.tsx
 delete mode 100644 src/components/Widgets/CVPreview/CVPreview.module.scss
 delete mode 100644 src/components/Widgets/CVPreview/CVPreview.tsx
 delete mode 100644 src/components/Widgets/RecentPosts/RecentPosts.module.scss
 delete mode 100644 src/components/Widgets/RecentPosts/RecentPosts.tsx
 delete mode 100644 src/components/Widgets/RelatedThematics/RelatedThematics.tsx
 delete mode 100644 src/components/Widgets/RelatedTopics/RelatedTopics.tsx
 delete mode 100644 src/components/Widgets/Sharing/Sharing.module.scss
 delete mode 100644 src/components/Widgets/Sharing/Sharing.tsx
 delete mode 100644 src/components/Widgets/SocialMedia/SocialMedia.module.scss
 delete mode 100644 src/components/Widgets/SocialMedia/SocialMedia.tsx
 delete mode 100644 src/components/Widgets/ThematicsList/ThematicsList.tsx
 delete mode 100644 src/components/Widgets/ToC/ToC.tsx
 delete mode 100644 src/components/Widgets/TopicsList/TopicsList.tsx
 delete mode 100644 src/components/Widgets/index.tsx
 delete mode 100644 src/pages/404.tsx
 delete mode 100644 src/pages/article/[slug].tsx
 delete mode 100644 src/pages/blog/index.tsx
 delete mode 100644 src/pages/blog/page/[id].tsx
 delete mode 100644 src/pages/contact.tsx
 delete mode 100644 src/pages/cv.tsx
 delete mode 100644 src/pages/index.tsx
 delete mode 100644 src/pages/mentions-legales.tsx
 delete mode 100644 src/pages/projet/[slug].tsx
 delete mode 100644 src/pages/projets.tsx
 delete mode 100644 src/pages/recherche/index.tsx
 delete mode 100644 src/pages/sujet/[slug].tsx
 delete mode 100644 src/pages/thematique/[slug].tsx
 delete mode 100644 src/services/graphql/api.ts
 delete mode 100644 src/services/graphql/mutations.ts
 delete mode 100644 src/services/graphql/queries.ts
 delete mode 100644 src/ts/types/app.ts
 delete mode 100644 src/ts/types/articles.ts
 delete mode 100644 src/ts/types/blog.ts
 delete mode 100644 src/ts/types/comments.ts
 delete mode 100644 src/ts/types/contact.ts
 delete mode 100644 src/ts/types/cover.ts
 delete mode 100644 src/ts/types/nav.ts
 delete mode 100644 src/ts/types/prism.ts
 delete mode 100644 src/ts/types/repos.ts
 delete mode 100644 src/ts/types/seo.ts
 delete mode 100644 src/ts/types/taxonomies.ts
 delete mode 100644 src/utils/helpers/format.ts
 delete mode 100644 src/utils/helpers/prism.ts
 delete mode 100644 src/utils/helpers/projects.ts
 delete mode 100644 src/utils/helpers/sort.ts
 delete mode 100644 src/utils/hooks/useGithubApi.tsx
 delete mode 100644 src/utils/hooks/useHeadingsTree.tsx

(limited to '__tests__/jest/components/Copyright.test.tsx')

diff --git a/__tests__/jest/components/Branding.test.tsx b/__tests__/jest/components/Branding.test.tsx
deleted file mode 100644
index 14266be..0000000
--- a/__tests__/jest/components/Branding.test.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import Branding from '@components/Branding/Branding';
-import { render, screen } from '@test-utils';
-
-describe('Branding', () => {
-  it('renders the title wrapped with an h1 element on homepage', () => {
-    render(<Branding isHome={true} />);
-    expect(
-      screen.getByRole('heading', { level: 1, name: 'Armand Philippot' })
-    ).toBeInTheDocument();
-  });
-
-  it('renders the title wrapped without an h1 element on other pages', () => {
-    render(<Branding isHome={false} />);
-    expect(
-      screen.queryByRole('heading', { level: 1, name: 'Armand Philippot' })
-    ).not.toBeInTheDocument();
-  });
-
-  it('renders the baseline', () => {
-    render(<Branding isHome={false} />);
-    // Currently, only French translation is returned.
-    expect(screen.getByText('Intégrateur web')).toBeInTheDocument();
-  });
-});
diff --git a/__tests__/jest/components/Copyright.test.tsx b/__tests__/jest/components/Copyright.test.tsx
deleted file mode 100644
index 08beb50..0000000
--- a/__tests__/jest/components/Copyright.test.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import Copyright from '@components/Copyright/Copyright';
-import { render, screen } from '@test-utils';
-
-describe('Copyright', () => {
-  it('renders the Copyright component', () => {
-    render(<Copyright />);
-  });
-
-  it('displays author name', () => {
-    render(<Copyright />);
-    expect(screen.getByText('Armand Philippot')).toBeInTheDocument();
-  });
-});
diff --git a/__tests__/jest/components/Header.test.tsx b/__tests__/jest/components/Header.test.tsx
deleted file mode 100644
index 44c6871..0000000
--- a/__tests__/jest/components/Header.test.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import Header from '@components/Header/Header';
-import { render } from '@test-utils';
-
-// Toolbar uses forwardRef. Without mocking an error occurred.
-jest.mock('@components/Toolbar/Toolbar', () => 'div');
-
-describe('Header', () => {
-  it('renders the Header component', () => {
-    const { container } = render(<Header isHome={false} />);
-    expect(container).toBeTruthy();
-  });
-});
diff --git a/src/components/Branding/Branding.module.scss b/src/components/Branding/Branding.module.scss
deleted file mode 100644
index 2cd3b15..0000000
--- a/src/components/Branding/Branding.module.scss
+++ /dev/null
@@ -1,169 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-
-.wrapper {
-  --logo-size: clamp(#{fun.convert-px(68)}, 18vw, #{fun.convert-px(100)});
-
-  display: grid;
-  grid-template-columns:
-    var(--logo-size)
-    minmax(0, 1fr);
-  grid-template-rows: repeat(2, max-content);
-  align-items: center;
-  column-gap: var(--spacing-sm);
-  padding: var(--spacing-sm) 0;
-  text-shadow: fun.convert-px(2) fun.convert-px(2) 0 var(--color-fg-inverted);
-}
-
-.logo {
-  --branding-logo-animation: none;
-
-  grid-column: 1;
-  grid-row: 1 / -1;
-  justify-self: center;
-  display: flex;
-  place-content: center;
-  width: var(--logo-size);
-  height: var(--logo-size);
-  position: relative;
-  border-radius: 50%;
-  transition: all 0.6s linear 0s;
-  transform-style: preserve-3d;
-  animation: var(--branding-logo-animation);
-
-  &__front,
-  &__back {
-    width: 100%;
-    height: 100%;
-    padding: fun.convert-px(2);
-    position: absolute;
-    top: 0;
-    left: 0;
-    backface-visibility: hidden;
-    background: var(--color-bg);
-    border: fun.convert-px(2) solid var(--color-primary-dark);
-    border-radius: 50%;
-    transition: all 0.6s linear 0s;
-  }
-
-  &__front {
-    box-shadow: fun.convert-px(1) fun.convert-px(2) fun.convert-px(1) 0
-        var(--color-shadow-light),
-      fun.convert-px(2) fun.convert-px(3) fun.convert-px(3) 0
-        var(--color-shadow-light);
-  }
-
-  &__back {
-    transform: rotateY(180deg);
-  }
-
-  img,
-  svg {
-    border-radius: 50%;
-  }
-
-  &:hover {
-    transform: rotateY(180deg);
-  }
-
-  &:hover & {
-    &__front {
-      box-shadow: none;
-    }
-
-    &__back {
-      box-shadow: fun.convert-px(1) fun.convert-px(2) fun.convert-px(1) 0
-          var(--color-shadow-light),
-        fun.convert-px(2) fun.convert-px(3) fun.convert-px(3) 0
-          var(--color-shadow-light);
-    }
-  }
-}
-
-.name {
-  --branding-name-animation: none;
-
-  grid-column: 2;
-  grid-row: 1;
-  margin: 0;
-  font-family: var(--font-family-secondary);
-  font-size: clamp(var(--font-size-xl), 6vw, var(--font-size-2xl));
-  font-weight: 500;
-  letter-spacing: 0.01ex;
-  position: relative;
-  overflow: hidden;
-
-  &::after {
-    content: "|";
-    display: block;
-    width: 100%;
-    height: 100%;
-    position: absolute;
-    top: 0;
-    right: 0;
-    background: var(--color-bg);
-    color: var(--color-primary-darker);
-    font-weight: 400;
-    visibility: hidden;
-    transform: translateX(100%);
-    transform-origin: right;
-    animation: var(--branding-name-animation);
-  }
-}
-
-.job {
-  --branding-job-animation: none;
-
-  grid-column: 2;
-  grid-row: 2;
-  width: max-content;
-  margin: 0;
-  color: var(--color-fg-light);
-  font-family: var(--font-family-secondary);
-  font-size: var(--font-size-lg);
-  font-weight: 500;
-  position: relative;
-  overflow: hidden;
-
-  &::after {
-    content: "|";
-    display: block;
-    width: 100%;
-    height: 100%;
-    position: absolute;
-    top: 0;
-    right: 0;
-    background: var(--color-bg);
-    color: var(--color-primary-darker);
-    font-weight: 400;
-    visibility: hidden;
-    transform: translateX(100%);
-    transform-origin: right;
-    animation: var(--branding-job-animation);
-  }
-}
-
-.link {
-  background: linear-gradient(
-      to top,
-      var(--color-primary-light) fun.convert-px(5),
-      transparent fun.convert-px(5)
-    )
-    left / 0 100% no-repeat;
-  text-decoration: none;
-  transition: all 0.6s ease-out 0s;
-
-  &:hover,
-  &:focus {
-    background-size: 100% 100%;
-  }
-
-  &:focus {
-    color: var(--color-primary-light);
-  }
-
-  &:active {
-    background-size: 0 100%;
-    color: var(--color-primary-dark);
-  }
-}
diff --git a/src/components/Branding/Branding.tsx b/src/components/Branding/Branding.tsx
deleted file mode 100644
index b19116d..0000000
--- a/src/components/Branding/Branding.tsx
+++ /dev/null
@@ -1,107 +0,0 @@
-import photo from '@assets/images/armand-philippot.jpg';
-import { settings } from '@utils/config';
-import Image from 'next/image';
-import Link from 'next/link';
-import { useRouter } from 'next/router';
-import Script from 'next/script';
-import { ReactElement, useEffect, useRef } from 'react';
-import { useIntl } from 'react-intl';
-import { Person, WithContext } from 'schema-dts';
-import styles from './Branding.module.scss';
-import Logo from './Logo/Logo';
-
-type BrandingReturn = ({ isHome }: { isHome: boolean }) => ReactElement;
-
-const Branding: BrandingReturn = ({ isHome = false }) => {
-  const intl = useIntl();
-  const { locale } = useRouter();
-  const TitleTag = isHome ? 'h1' : 'p';
-  const logoRef = useRef<HTMLDivElement>(null);
-  const titleRef = useRef<HTMLHeadingElement | HTMLParagraphElement>(null);
-  const jobRef = useRef<HTMLParagraphElement>(null);
-
-  useEffect(() => {
-    if (logoRef.current) {
-      logoRef.current.style.setProperty(
-        '--branding-logo-animation',
-        'flip-logo 9s ease-in 0s 1'
-      );
-    }
-  }, []);
-
-  useEffect(() => {
-    if (titleRef.current) {
-      titleRef.current.style.setProperty(
-        '--branding-name-animation',
-        'blink 0.8s ease-in-out 0s 2, typing 4.3s linear 0s 1'
-      );
-    }
-  }, []);
-
-  useEffect(() => {
-    if (jobRef.current) {
-      jobRef.current.style.setProperty(
-        '--branding-job-animation',
-        'hide-text 4.25s linear 0s 1, blink 0.8s ease-in-out 4.25s 2, typing 3.8s linear 4.25s 1'
-      );
-    }
-  }, []);
-
-  const schemaJsonLd: WithContext<Person> = {
-    '@context': 'https://schema.org',
-    '@type': 'Person',
-    '@id': `${settings.url}/#branding`,
-    name: settings.name,
-    url: settings.url,
-    jobTitle: locale?.startsWith('en')
-      ? settings.baseline.en
-      : settings.baseline.fr,
-    image: photo.src,
-    subjectOf: { '@id': `${settings.url}` },
-  };
-
-  return (
-    <>
-      <Script
-        id="schema-branding"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      <div id="branding" className={styles.wrapper}>
-        <div className={styles.logo} ref={logoRef}>
-          <div className={styles.logo__front}>
-            <Image
-              src={photo}
-              alt={intl.formatMessage(
-                {
-                  defaultMessage: '{brandingName} picture',
-                  description: 'Branding: branding name picture.',
-                  id: 'ILRLTq',
-                },
-                {
-                  brandingName: settings.name,
-                }
-              )}
-              layout="responsive"
-            />
-          </div>
-          <div className={styles.logo__back}>
-            <Logo />
-          </div>
-        </div>
-        <TitleTag ref={titleRef} className={styles.name}>
-          <Link href="/">
-            <a className={styles.link}>{settings.name}</a>
-          </Link>
-        </TitleTag>
-        <p ref={jobRef} className={styles.job}>
-          {locale?.startsWith('en')
-            ? settings.baseline.en
-            : settings.baseline.fr}
-        </p>
-      </div>
-    </>
-  );
-};
-
-export default Branding;
diff --git a/src/components/Branding/Logo/Logo.module.scss b/src/components/Branding/Logo/Logo.module.scss
deleted file mode 100644
index 3d62bf9..0000000
--- a/src/components/Branding/Logo/Logo.module.scss
+++ /dev/null
@@ -1,23 +0,0 @@
-.wrapper {
-  position: relative;
-}
-
-.bg-left {
-  fill: var(--color-primary-light);
-}
-
-.bg-right {
-  fill: var(--color-primary-dark);
-}
-
-.letter {
-  fill: var(--color-fg-inverted);
-  stroke: var(--color-primary-darker);
-  stroke-width: 5;
-}
-
-.letter-shadow {
-  fill: var(--color-shadow-darker);
-  stroke: var(--color-shadow-darker);
-  stroke-width: 5;
-}
diff --git a/src/components/Branding/Logo/Logo.tsx b/src/components/Branding/Logo/Logo.tsx
deleted file mode 100644
index 0623042..0000000
--- a/src/components/Branding/Logo/Logo.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import styles from './Logo.module.scss';
-
-const Logo = () => {
-  return (
-    <svg
-      viewBox="0 0 512 512"
-      xmlns="http://www.w3.org/2000/svg"
-      className={styles.wrapper}
-    >
-      <path className={styles['bg-left']} d="M 0,0 H 506 L 0,506 Z" />
-      <path className={styles['bg-right']} d="M 512,512 H 6 L 512,6 Z" />
-      <path
-        className={styles['letter-shadow']}
-        d="m 66.049088,353.26557 h 57.233082 l 15.4763,-40.00476 h 56.64908 l 15.76831,40.00476 h 57.2331 L 196.28357,165.21398 h -58.10911 z m 80.009522,-79.42552 21.02441,-55.18904 21.02439,55.18904 z"
-      />
-      <path
-        className={styles['letter']}
-        d="m 59.569539,346.78602 h 57.233081 l 15.4763,-40.00476 H 188.928 l 15.76831,40.00476 h 57.2331 L 189.80402,158.73443 h -58.10911 z m 80.009521,-79.42552 21.02441,-55.18904 21.02439,55.18904 z"
-      />
-      <path
-        className={styles['letter-shadow']}
-        d="m 288.84935,353.26557 h 54.89704 v -50.51696 h 40.88078 c 42.04881,0 68.91332,-28.61654 68.91332,-68.32931 0,-38.5447 -21.60841,-69.20532 -67.74528,-69.20532 h -96.94586 z m 54.89704,-92.56578 v -53.437 h 29.78458 c 16.35231,0 23.94446,10.51221 23.94446,27.15651 0,15.47629 -8.46817,26.28049 -25.40449,26.28049 z"
-      />
-      <path
-        className={styles['letter']}
-        d="m 282.3698,346.78602 h 54.89704 v -50.51696 h 40.88078 c 42.04881,0 68.91332,-28.61654 68.91332,-68.3293 0,-38.54471 -21.60841,-69.20533 -67.74528,-69.20533 H 282.3698 Z m 54.89704,-92.56578 v -53.437 h 29.78458 c 16.35231,0 23.94446,10.51221 23.94446,27.15652 0,15.47628 -8.46817,26.28048 -25.40449,26.28048 z"
-      />
-    </svg>
-  );
-};
-
-export default Logo;
diff --git a/src/components/Breadcrumb/Breadcrumb.module.scss b/src/components/Breadcrumb/Breadcrumb.module.scss
deleted file mode 100644
index b8fadf8..0000000
--- a/src/components/Breadcrumb/Breadcrumb.module.scss
+++ /dev/null
@@ -1,29 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-@use "@styles/abstracts/placeholders";
-
-.wrapper {
-  composes: grid from "@styles/layout/_grid.scss";
-  padding: var(--spacing-md) 0;
-}
-
-.list {
-  @extend %reset-ordered-list;
-
-  grid-column: 2;
-  display: flex;
-  flex-flow: row wrap;
-  align-items: center;
-  gap: var(--spacing-2xs);
-  margin: 0;
-  font-size: var(--font-size-sm);
-}
-
-.item {
-  &:not(:last-of-type) {
-    &::after {
-      content: ">";
-      margin-left: var(--spacing-2xs);
-    }
-  }
-}
diff --git a/src/components/Breadcrumb/Breadcrumb.tsx b/src/components/Breadcrumb/Breadcrumb.tsx
deleted file mode 100644
index a7b945a..0000000
--- a/src/components/Breadcrumb/Breadcrumb.tsx
+++ /dev/null
@@ -1,155 +0,0 @@
-import { settings } from '@utils/config';
-import Link from 'next/link';
-import { useRouter } from 'next/router';
-import Script from 'next/script';
-import { useIntl } from 'react-intl';
-import { BreadcrumbList, WithContext } from 'schema-dts';
-import styles from './Breadcrumb.module.scss';
-
-const Breadcrumb = ({ pageTitle }: { pageTitle: string }) => {
-  const intl = useIntl();
-  const router = useRouter();
-
-  const isHome = router.pathname === '/';
-  const isArticle = router.pathname.includes('/article/');
-  const isProject = router.pathname.includes('/projet/');
-  const isSubject = router.pathname.includes('/sujet/');
-  const isThematic = router.pathname.includes('/thematique/');
-
-  const getItems = () => {
-    return (
-      <>
-        <li className={styles.item}>
-          <Link href="/">
-            <a>
-              {intl.formatMessage({
-                defaultMessage: 'Home',
-                description: 'Breadcrumb: Home item',
-                id: 'Enij19',
-              })}
-            </a>
-          </Link>
-        </li>
-        {(isArticle || isThematic || isSubject) && (
-          <>
-            <li className={styles.item}>
-              <Link href="/blog">
-                <a>
-                  {intl.formatMessage({
-                    defaultMessage: 'Blog',
-                    description: 'Breadcrumb: Blog item',
-                    id: 'z0ic9c',
-                  })}
-                </a>
-              </Link>
-            </li>
-          </>
-        )}
-        {isProject && (
-          <>
-            <li className={styles.item}>
-              <Link href="/projets">
-                <a>
-                  {intl.formatMessage({
-                    defaultMessage: 'Projects',
-                    description: 'Breadcrumb: Projects item',
-                    id: 'Igx3qp',
-                  })}
-                </a>
-              </Link>
-            </li>
-          </>
-        )}
-        <li className="screen-reader-text">{pageTitle}</li>
-      </>
-    );
-  };
-
-  const getElementsSchema = () => {
-    const items = [];
-    const homepage: BreadcrumbList['itemListElement'] = {
-      '@type': 'ListItem',
-      position: 1,
-      name: intl.formatMessage({
-        defaultMessage: 'Home',
-        description: 'Breadcrumb: Home item',
-        id: 'Enij19',
-      }),
-      item: settings.url,
-    };
-
-    items.push(homepage);
-
-    if (isArticle || isThematic || isSubject) {
-      const blog: BreadcrumbList['itemListElement'] = {
-        '@type': 'ListItem',
-        position: 2,
-        name: intl.formatMessage({
-          defaultMessage: 'Blog',
-          description: 'Breadcrumb: Blog item',
-          id: 'z0ic9c',
-        }),
-        item: `${settings.url}/blog`,
-      };
-
-      items.push(blog);
-    }
-
-    if (isProject) {
-      const blog: BreadcrumbList['itemListElement'] = {
-        '@type': 'ListItem',
-        position: 2,
-        name: intl.formatMessage({
-          defaultMessage: 'Projects',
-          description: 'Breadcrumb: Projects item',
-          id: 'Igx3qp',
-        }),
-        item: `${settings.url}/projets`,
-      };
-
-      items.push(blog);
-    }
-
-    const currentPage: BreadcrumbList['itemListElement'] = {
-      '@type': 'ListItem',
-      position: items.length + 1,
-      name: pageTitle,
-      item: `${settings.url}${router.asPath}`,
-    };
-
-    items.push(currentPage);
-
-    return items;
-  };
-
-  const schemaJsonLd: WithContext<BreadcrumbList> = {
-    '@context': 'https://schema.org',
-    '@type': 'BreadcrumbList',
-    '@id': `${settings.url}/#breadcrumb`,
-    itemListElement: getElementsSchema(),
-  };
-
-  return (
-    <>
-      <Script
-        id="schema-breadcrumb"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      {!isHome && (
-        <nav id="breadcrumb" className={styles.wrapper}>
-          <span className="screen-reader-text">
-            {intl.formatMessage({
-              defaultMessage: 'You are here:',
-              description: 'Breadcrumb: You are here prefix',
-              id: '16zl9Z',
-            })}
-          </span>
-          <ol className={styles.list}>{getItems()}</ol>
-        </nav>
-      )}
-    </>
-  );
-};
-
-export default Breadcrumb;
diff --git a/src/components/Buttons/Button/Button.tsx b/src/components/Buttons/Button/Button.tsx
deleted file mode 100644
index ada23fe..0000000
--- a/src/components/Buttons/Button/Button.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import { ButtonKind, ButtonPosition } from '@ts/types/app';
-import { ReactNode } from 'react';
-import styles from '../Buttons.module.scss';
-
-const Button = ({
-  children,
-  clickHandler,
-  kind = 'secondary',
-  position = 'left',
-  spacing = false,
-  isDisabled = false,
-}: {
-  children: ReactNode;
-  clickHandler: any;
-  kind?: ButtonKind;
-  position?: ButtonPosition;
-  spacing?: boolean;
-  isDisabled?: boolean;
-}) => {
-  const spacingClass = spacing ? styles.spacing : '';
-  const classes = `${styles.btn} ${styles[position]} ${styles[kind]} ${spacingClass}`;
-
-  return (
-    <button
-      className={classes}
-      type="button"
-      disabled={isDisabled}
-      onClick={clickHandler}
-    >
-      {children}
-    </button>
-  );
-};
-
-export default Button;
diff --git a/src/components/Buttons/ButtonHelp/ButtonHelp.module.scss b/src/components/Buttons/ButtonHelp/ButtonHelp.module.scss
deleted file mode 100644
index b2a05d7..0000000
--- a/src/components/Buttons/ButtonHelp/ButtonHelp.module.scss
+++ /dev/null
@@ -1,52 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-
-.icon {
-  color: var(--color-primary-dark);
-  font-weight: 600;
-}
-
-.active {
-  .icon {
-    color: var(--color-fg-inverted);
-  }
-}
-
-.wrapper {
-  width: fun.convert-px(44);
-  height: fun.convert-px(44);
-  background: var(--color-bg);
-  border: fun.convert-px(3) solid var(--color-primary-dark);
-  border-radius: 50%;
-  box-shadow: fun.convert-px(1) fun.convert-px(1) 0 0 var(--color-shadow);
-  transition: all 0.3s ease-in-out 0s;
-
-  @include mix.pointer("fine") {
-    width: fun.convert-px(30);
-    height: fun.convert-px(30);
-    line-height: 1;
-  }
-
-  &:hover,
-  &:focus {
-    border-color: var(--color-primary-light);
-    color: var(--color-primary-light);
-    box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1)
-        var(--color-shadow-light),
-      fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-2)
-        var(--color-shadow-light),
-      fun.convert-px(3) fun.convert-px(4) fun.convert-px(5) fun.convert-px(-4)
-        var(--color-shadow-light),
-      fun.convert-px(7) fun.convert-px(10) fun.convert-px(12) fun.convert-px(-3)
-        var(--color-shadow-light);
-    transform: scale(1.1);
-
-    .icon {
-      transform: scale(1.1);
-    }
-  }
-
-  &.active {
-    background: var(--color-primary);
-  }
-}
diff --git a/src/components/Buttons/ButtonHelp/ButtonHelp.tsx b/src/components/Buttons/ButtonHelp/ButtonHelp.tsx
deleted file mode 100644
index 2616a8f..0000000
--- a/src/components/Buttons/ButtonHelp/ButtonHelp.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { SetStateAction } from 'react';
-import { useIntl } from 'react-intl';
-import styles from './ButtonHelp.module.scss';
-
-const ButtonHelp = ({
-  showHelp,
-  setShowHelp,
-  title,
-}: {
-  showHelp: boolean;
-  setShowHelp: (value: SetStateAction<boolean>) => void;
-  title?: string;
-}) => {
-  const intl = useIntl();
-
-  const handleClick = () => {
-    setShowHelp((prev) => !prev);
-  };
-
-  const activeModifier = showHelp ? styles.active : '';
-
-  return (
-    <button
-      onClick={handleClick}
-      title={title}
-      className={`${styles.wrapper} ${activeModifier}`}
-    >
-      <span className={styles.icon} aria-hidden="true">
-        ?
-      </span>
-      <span className="screen-reader-text">
-        {intl.formatMessage({
-          defaultMessage: 'Help',
-          description: 'ButtonHelp: screen reader text',
-          id: 'oPf+XA',
-        })}
-      </span>
-    </button>
-  );
-};
-
-export default ButtonHelp;
diff --git a/src/components/Buttons/ButtonLink/ButtonLink.tsx b/src/components/Buttons/ButtonLink/ButtonLink.tsx
deleted file mode 100644
index 179c686..0000000
--- a/src/components/Buttons/ButtonLink/ButtonLink.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { ButtonPosition } from '@ts/types/app';
-import Link from 'next/link';
-import { ReactNode } from 'react';
-import styles from '../Buttons.module.scss';
-
-const ButtonLink = ({
-  children,
-  target,
-  position = 'left',
-  isExternal = false,
-}: {
-  children: ReactNode;
-  target: string;
-  position?: ButtonPosition;
-  isExternal?: boolean;
-}) => {
-  const classes = `${styles.btn} ${styles[position]} ${styles.tertiary}`;
-
-  return isExternal ? (
-    <a className={classes} href={target}>
-      {children}
-    </a>
-  ) : (
-    <Link href={target}>
-      <a className={classes}>{children}</a>
-    </Link>
-  );
-};
-
-export default ButtonLink;
diff --git a/src/components/Buttons/ButtonSubmit/ButtonSubmit.tsx b/src/components/Buttons/ButtonSubmit/ButtonSubmit.tsx
deleted file mode 100644
index 4725cad..0000000
--- a/src/components/Buttons/ButtonSubmit/ButtonSubmit.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { ReactNode } from 'react';
-import styles from '../Buttons.module.scss';
-
-type Modifier = 'search' | 'submit';
-
-const ButtonSubmit = ({
-  children,
-  modifier = 'submit',
-}: {
-  children: ReactNode;
-  modifier?: Modifier;
-}) => {
-  const withModifier = modifier === 'search' ? styles.search : styles.primary;
-
-  return (
-    <button type="submit" className={`${styles.btn} ${withModifier}`}>
-      {children}
-    </button>
-  );
-};
-
-export default ButtonSubmit;
diff --git a/src/components/Buttons/ButtonToolbar/ButtonToolbar.tsx b/src/components/Buttons/ButtonToolbar/ButtonToolbar.tsx
deleted file mode 100644
index 7ceb70d..0000000
--- a/src/components/Buttons/ButtonToolbar/ButtonToolbar.tsx
+++ /dev/null
@@ -1,72 +0,0 @@
-import { CloseIcon, CogIcon, SearchIcon } from '@components/Icons';
-import { ForwardedRef, forwardRef, SetStateAction } from 'react';
-import { useIntl } from 'react-intl';
-import styles from '../Buttons.module.scss';
-
-type ButtonType = 'search' | 'settings';
-
-const ButtonToolbar = (
-  {
-    type,
-    isActivated,
-    setIsActivated,
-  }: {
-    type: ButtonType;
-    isActivated: boolean;
-    setIsActivated: (value: SetStateAction<boolean>) => void;
-  },
-  ref: ForwardedRef<HTMLButtonElement>
-) => {
-  const intl = useIntl();
-  const ButtonIcon = () => (type === 'search' ? <SearchIcon /> : <CogIcon />);
-  const btnClasses = isActivated
-    ? `${styles.toolbar} ${styles['toolbar--activated']}`
-    : styles.toolbar;
-
-  return (
-    <button
-      ref={ref}
-      className={btnClasses}
-      type="button"
-      onClick={() => setIsActivated(!isActivated)}
-    >
-      <span className={styles.icon}>
-        <span className={styles.front}>
-          <ButtonIcon />
-        </span>
-        <span className={styles.back}>
-          <CloseIcon />
-        </span>
-      </span>
-      {isActivated ? (
-        <span className="screen-reader-text">
-          {intl.formatMessage(
-            {
-              defaultMessage: 'Close {type}',
-              description: 'ButtonToolbar: Close button',
-              id: 'SWq8a4',
-            },
-            {
-              type,
-            }
-          )}
-        </span>
-      ) : (
-        <span className="screen-reader-text">
-          {intl.formatMessage(
-            {
-              defaultMessage: 'Open {type}',
-              description: 'ButtonToolbar: Open button',
-              id: 'Z1eSIz',
-            },
-            {
-              type,
-            }
-          )}
-        </span>
-      )}
-    </button>
-  );
-};
-
-export default forwardRef(ButtonToolbar);
diff --git a/src/components/Buttons/Buttons.module.scss b/src/components/Buttons/Buttons.module.scss
deleted file mode 100644
index 0ea9289..0000000
--- a/src/components/Buttons/Buttons.module.scss
+++ /dev/null
@@ -1,289 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-@use "@styles/abstracts/placeholders";
-
-.btn {
-  display: block;
-  border: none;
-  font-size: var(--font-size-md);
-}
-
-.left {
-  margin-right: auto;
-}
-
-.right {
-  margin-left: auto;
-}
-
-.center {
-  margin-left: auto;
-  margin-right: auto;
-}
-
-.primary {
-  margin: auto;
-  padding: var(--spacing-2xs) var(--spacing-md);
-  background: var(--color-primary);
-  border: fun.convert-px(2) solid var(--color-bg);
-  border-radius: fun.convert-px(5);
-  box-shadow: 0 0 0 fun.convert-px(2) var(--color-primary),
-    0 0 0 fun.convert-px(3) var(--color-primary-darker),
-    fun.convert-px(2) fun.convert-px(2) 0 fun.convert-px(3)
-      var(--color-primary-dark);
-  color: var(--color-fg-inverted);
-  font-weight: 600;
-  text-shadow: fun.convert-px(2) fun.convert-px(2) 0 var(--color-shadow);
-  transition: all 0.25s ease-in-out 0s;
-
-  &:hover,
-  &:focus {
-    background: var(--color-primary-light);
-    box-shadow: 0 0 0 fun.convert-px(2) var(--color-primary-light),
-      0 0 0 fun.convert-px(3) var(--color-primary-darker),
-      fun.convert-px(7) fun.convert-px(7) 0 fun.convert-px(2)
-        var(--color-primary-dark);
-    transform: translateX(#{fun.convert-px(-4)})
-      translateY(#{fun.convert-px(-4)});
-  }
-
-  &:focus {
-    text-decoration: underline solid var(--color-fg-inverted) fun.convert-px(2);
-  }
-
-  &:active {
-    background: var(--color-primary-dark);
-    box-shadow: 0 0 0 fun.convert-px(2) var(--color-primary),
-      0 0 0 fun.convert-px(3) var(--color-primary-darker),
-      0 0 0 0 var(--color-primary-dark);
-    text-decoration: none;
-    transform: translateX(#{fun.convert-px(4)}) translateY(#{fun.convert-px(4)});
-  }
-}
-
-.secondary {
-  padding: var(--spacing-2xs) var(--spacing-md);
-  background: var(--color-bg);
-  border: fun.convert-px(3) solid var(--color-primary);
-  border-radius: fun.convert-px(5);
-  box-shadow: fun.convert-px(2) fun.convert-px(2) 0 0 var(--color-bg),
-    fun.convert-px(3) fun.convert-px(3) 0 0 var(--color-primary-dark),
-    fun.convert-px(5) fun.convert-px(5) 0 0 var(--color-bg),
-    fun.convert-px(6) fun.convert-px(6) 0 0 var(--color-primary-dark);
-  color: var(--color-primary);
-  font-weight: 600;
-  transition: all 0.35s ease-out 0s;
-
-  &:disabled {
-    color: var(--color-fg-light);
-    border-color: var(--color-border-dark);
-    box-shadow: fun.convert-px(2) fun.convert-px(2) 0 0 var(--color-bg),
-      fun.convert-px(3) fun.convert-px(3) 0 0 var(--color-primary-darker),
-      fun.convert-px(5) fun.convert-px(5) 0 0 var(--color-bg),
-      fun.convert-px(6) fun.convert-px(6) 0 0 var(--color-primary-darker);
-    cursor: wait;
-  }
-
-  &:not(:disabled) {
-    &:hover,
-    &:focus {
-      transform: translateX(#{fun.convert-px(-3)})
-        translateY(#{fun.convert-px(-5)});
-      border-color: var(--color-primary-light);
-      box-shadow: fun.convert-px(2) fun.convert-px(3) 0 0 var(--color-bg),
-        fun.convert-px(4) fun.convert-px(5) 0 0 var(--color-primary),
-        fun.convert-px(6) fun.convert-px(8) 0 0 var(--color-bg),
-        fun.convert-px(8) fun.convert-px(10) 0 0 var(--color-primary),
-        fun.convert-px(10) fun.convert-px(12) fun.convert-px(1) 0
-          var(--color-shadow-light),
-        fun.convert-px(10) fun.convert-px(12) fun.convert-px(5)
-          fun.convert-px(1) var(--color-shadow-light);
-      color: var(--color-primary-light);
-    }
-
-    &:focus {
-      text-decoration: underline var(--color-primary) fun.convert-px(2);
-    }
-
-    &:active {
-      text-decoration: none;
-      transform: translateX(#{fun.convert-px(5)})
-        translateY(#{fun.convert-px(6)});
-      box-shadow: 0 0 0 0 var(--color-shadow);
-    }
-  }
-}
-
-.tertiary {
-  display: flex;
-  flex-flow: row wrap;
-  place-items: center;
-  gap: var(--spacing-2xs);
-  width: max-content;
-  padding: var(--spacing-2xs) var(--spacing-sm);
-  position: relative;
-  background: var(--color-bg);
-  border: fun.convert-px(3) solid var(--color-primary);
-  border-radius: fun.convert-px(5);
-  box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1)
-      var(--color-shadow),
-    fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-2)
-      var(--color-shadow),
-    fun.convert-px(3) fun.convert-px(4) fun.convert-px(5) fun.convert-px(-4)
-      var(--color-shadow);
-  color: var(--color-primary);
-  font-weight: 600;
-  text-decoration: underline transparent 0;
-  transition: all 0.3s ease-in-out 0s, text-decoration 0.35s ease-in-out 0s;
-
-  &:hover,
-  &:focus {
-    border-color: var(--color-primary-light);
-    color: var(--color-primary-light);
-    box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1)
-        var(--color-shadow-light),
-      fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-2)
-        var(--color-shadow-light),
-      fun.convert-px(3) fun.convert-px(4) fun.convert-px(5) fun.convert-px(-4)
-        var(--color-shadow-light),
-      fun.convert-px(7) fun.convert-px(10) fun.convert-px(12) fun.convert-px(-3)
-        var(--color-shadow-light);
-    transform: scale(1.1);
-  }
-
-  &:focus {
-    text-decoration: underline var(--color-primary-light) fun.convert-px(3);
-  }
-
-  &:active {
-    border-color: var(--color-primary-dark);
-    color: var(--color-primary-dark);
-    box-shadow: 0 0 0 0 var(--color-shadow);
-    text-decoration: underline transparent 0;
-    transform: scale(0.94);
-  }
-}
-
-:global {
-  [data-theme="dark"] {
-    :local {
-      .tertiary {
-        img[src*="png"] {
-          background: none;
-        }
-      }
-    }
-  }
-}
-
-.toolbar {
-  --draw-border-thickness: #{fun.convert-px(4)};
-  --icon-size: 100%;
-
-  display: flex;
-  flex-flow: row nowrap;
-  place-items: center;
-  width: var(--btn-size, 100%);
-  height: var(--btn-size, 100%);
-  padding: var(--spacing-2xs);
-  background: none;
-  border: none;
-  font-size: var(--font-size-md);
-
-  &:hover,
-  &:focus {
-    --draw-border-color1: var(--color-primary-light);
-    --draw-border-color2: var(--color-primary-lighter);
-
-    @extend %draw-borders;
-  }
-
-  @include mix.media("screen") {
-    @include mix.dimensions("md") {
-      border-radius: 8%;
-    }
-  }
-}
-
-.icon {
-  display: block;
-  width: 100%;
-  height: 100%;
-  position: relative;
-  transform-style: preserve-3d;
-  transform: translate3d(0, 0, 0);
-  transition: all 0.5s ease-in-out 0s;
-}
-
-.front,
-.back {
-  display: flex;
-  place-content: center;
-  width: var(--icon-size);
-  height: var(--icon-size);
-  position: absolute;
-  top: 0;
-  right: 0;
-  transition: all 0.6s ease-in 0s;
-  backface-visibility: hidden;
-}
-
-.front {
-  transform: scale(1);
-  z-index: 20;
-}
-
-.back {
-  transform: scale(0.2) rotateY(180deg);
-  z-index: 10;
-}
-
-.toolbar--activated {
-  .icon {
-    transform: rotateY(180deg);
-  }
-
-  .front {
-    transform: scale(0.2);
-  }
-
-  .back {
-    transform: scale(1) rotateY(180deg);
-  }
-}
-
-.search {
-  background: transparent;
-  margin-left: calc(var(--btn-size) * -1);
-  z-index: 5;
-  transition: all 0.3s ease-in-out 0s;
-
-  svg {
-    transform: scale(0.85);
-    transition: all 0.3s ease-in-out 0s;
-  }
-
-  &:hover,
-  &:focus {
-    svg {
-      transform: scale(0.85) rotate(20deg) translateY(#{fun.convert-px(3)});
-    }
-  }
-
-  &:focus {
-    outline: var(--color-primary-light) solid fun.convert-px(3);
-  }
-
-  &:active {
-    outline: none;
-
-    svg {
-      transform: scale(0.7);
-    }
-  }
-}
-
-.spacing {
-  margin-top: var(--spacing-md);
-  margin-bottom: var(--spacing-md);
-}
diff --git a/src/components/Buttons/index.tsx b/src/components/Buttons/index.tsx
deleted file mode 100644
index 9b4b756..0000000
--- a/src/components/Buttons/index.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import Button from './Button/Button';
-import ButtonLink from './ButtonLink/ButtonLink';
-import ButtonToolbar from './ButtonToolbar/ButtonToolbar';
-import ButtonSubmit from './ButtonSubmit/ButtonSubmit';
-import ButtonHelp from './ButtonHelp/ButtonHelp';
-
-export { Button, ButtonHelp, ButtonLink, ButtonToolbar, ButtonSubmit };
diff --git a/src/components/Comment/Comment.module.scss b/src/components/Comment/Comment.module.scss
deleted file mode 100644
index dd52db2..0000000
--- a/src/components/Comment/Comment.module.scss
+++ /dev/null
@@ -1,99 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-
-.item {
-  margin: var(--spacing-sm) 0;
-}
-
-.wrapper {
-  background: var(--color-bg);
-  border: fun.convert-px(1) solid var(--color-border);
-  box-shadow: fun.convert-px(3) fun.convert-px(3) 0 0 var(--color-shadow-light),
-    fun.convert-px(4) fun.convert-px(4) fun.convert-px(3) fun.convert-px(-2)
-      var(--color-shadow);
-  padding: var(--spacing-md);
-  position: relative;
-
-  @include mix.media("screen") {
-    @include mix.dimensions("sm") {
-      display: grid;
-      grid-template-columns: minmax(#{fun.convert-px(150)}, 1fr) minmax(0, 85ch);
-      column-gap: var(--spacing-lg);
-    }
-  }
-}
-
-.header {
-  display: flex;
-  flex-flow: column wrap;
-  align-items: center;
-  row-gap: var(--spacing-sm);
-
-  @include mix.media("screen") {
-    @include mix.dimensions("sm") {
-      grid-row: 1 / 4;
-    }
-  }
-}
-
-.avatar {
-  width: fun.convert-px(85);
-  height: fun.convert-px(85);
-  margin: 0 auto;
-  border-radius: fun.convert-px(3);
-  box-shadow: 0 0 0 fun.convert-px(1) var(--color-shadow-light),
-    fun.convert-px(2) fun.convert-px(2) 0 fun.convert-px(1) var(--color-shadow);
-  position: relative;
-
-  img {
-    border-radius: fun.convert-px(3);
-  }
-}
-
-.author {
-  color: var(--color-primary-darker);
-  font-weight: 600;
-  text-align: center;
-}
-
-.date {
-  color: var(--color-fg-secondary);
-  font-size: var(--font-size-sm);
-  display: flex;
-  flex-flow: row wrap;
-  column-gap: var(--spacing-2xs);
-  justify-content: center;
-  margin: var(--spacing-md) 0;
-
-  @include mix.media("screen") {
-    @include mix.dimensions("sm") {
-      justify-content: left;
-      margin: 0 0 var(--spacing-md);
-    }
-  }
-}
-
-.body {
-  overflow-wrap: break-word;
-}
-
-.footer {
-  display: flex;
-  justify-content: flex-end;
-  align-items: center;
-  padding: var(--spacing-md) 0 0;
-
-  @include mix.media("screen") {
-    @include mix.dimensions("sm") {
-      padding: var(--spacing-sm) 0 0;
-    }
-  }
-
-  button {
-    margin: 0;
-  }
-}
-
-.list {
-  padding-left: var(--spacing-md);
-}
diff --git a/src/components/Comment/Comment.tsx b/src/components/Comment/Comment.tsx
deleted file mode 100644
index 355363b..0000000
--- a/src/components/Comment/Comment.tsx
+++ /dev/null
@@ -1,200 +0,0 @@
-import { Button } from '@components/Buttons';
-import Spinner from '@components/Spinner/Spinner';
-import { Comment as CommentData } from '@ts/types/comments';
-import { settings } from '@utils/config';
-import { getFormattedDate } from '@utils/helpers/format';
-import dynamic from 'next/dynamic';
-import Image from 'next/image';
-import Link from 'next/link';
-import { useRouter } from 'next/router';
-import Script from 'next/script';
-import { useState } from 'react';
-import { useIntl } from 'react-intl';
-import { Comment as CommentSchema, WithContext } from 'schema-dts';
-import styles from './Comment.module.scss';
-
-const DynamicCommentForm = dynamic(
-  () => import('@components/CommentForm/CommentForm'),
-  {
-    loading: () => <Spinner />,
-  }
-);
-
-const Comment = ({
-  articleId,
-  comment,
-  isNested = false,
-}: {
-  articleId: number;
-  comment: CommentData;
-  isNested?: boolean;
-}) => {
-  const intl = useIntl();
-  const router = useRouter();
-  const locale = router.locale ? router.locale : settings.locales.defaultLocale;
-  const [shouldOpenForm, setShouldOpenForm] = useState<boolean>(false);
-
-  const getCommentAuthor = () => {
-    return comment.author.url ? (
-      <Link href={comment.author.url}>
-        <a className={styles.author}>{comment.author.name}</a>
-      </Link>
-    ) : (
-      <span className={styles.author}>{comment.author.name}</span>
-    );
-  };
-
-  const getLocaleDate = () => {
-    const date = getFormattedDate(comment.date, locale);
-    const time = new Date(comment.date)
-      .toLocaleTimeString(locale, {
-        hour: 'numeric',
-        minute: 'numeric',
-      })
-      .replace(':', 'h');
-    return intl.formatMessage(
-      {
-        defaultMessage: '{date} at {time}',
-        description: 'Comment: publication date',
-        id: 'CT3ydM',
-      },
-      {
-        date,
-        time,
-      }
-    );
-  };
-
-  const getApprovedComment = () => {
-    return (
-      <>
-        <article
-          className={styles.wrapper}
-          id={`comment-${comment.databaseId}`}
-        >
-          <header className={styles.header}>
-            {comment.author.gravatarUrl && (
-              <div className={styles.avatar}>
-                <Image
-                  src={comment.author.gravatarUrl}
-                  alt={comment.author.name}
-                  layout="fill"
-                />
-              </div>
-            )}
-            {getCommentAuthor()}
-          </header>
-          <dl className={styles.date}>
-            <dt>
-              {intl.formatMessage({
-                defaultMessage: 'Published on:',
-                description: 'Comment: publication date label',
-                id: 'soj7do',
-              })}
-            </dt>
-            <dd>
-              <time dateTime={comment.date}>
-                <Link href={`#comment-${comment.databaseId}`}>
-                  <a>{getLocaleDate()}</a>
-                </Link>
-              </time>
-            </dd>
-          </dl>
-          <div
-            className={styles.body}
-            dangerouslySetInnerHTML={{ __html: comment.content }}
-          ></div>
-          {!isNested && (
-            <footer className={styles.footer}>
-              <Button clickHandler={() => setShouldOpenForm((prev) => !prev)}>
-                {shouldOpenForm
-                  ? intl.formatMessage({
-                      defaultMessage: 'Cancel reply',
-                      description: 'Comment: reply button',
-                      id: 'e1Forh',
-                    })
-                  : intl.formatMessage({
-                      defaultMessage: 'Reply',
-                      description: 'Comment: reply button',
-                      id: 'hzHuCc',
-                    })}
-              </Button>
-            </footer>
-          )}
-        </article>
-        {shouldOpenForm && (
-          <DynamicCommentForm
-            articleId={articleId}
-            parentId={comment.databaseId}
-          />
-        )}
-        {comment.replies.length > 0 && (
-          <ol className={styles.list}>
-            {comment.replies.map((reply) => {
-              return (
-                <Comment
-                  articleId={articleId}
-                  key={reply.databaseId}
-                  comment={reply}
-                  isNested={true}
-                />
-              );
-            })}
-          </ol>
-        )}
-      </>
-    );
-  };
-
-  const getCommentStatus = () => {
-    return (
-      <p>
-        {intl.formatMessage({
-          defaultMessage: 'This comment is awaiting moderation.',
-          description: 'Comment: awaiting moderation message',
-          id: 'rXeTkM',
-        })}
-      </p>
-    );
-  };
-
-  const schemaJsonLd: WithContext<CommentSchema> = {
-    '@context': 'https://schema.org',
-    '@id': `${settings.url}/#comment-${comment.databaseId}`,
-    '@type': 'Comment',
-    parentItem: isNested
-      ? { '@id': `${settings.url}/#comment-${comment.parentDatabaseId}` }
-      : undefined,
-    about: { '@type': 'Article', '@id': `${settings.url}/#article` },
-    author: {
-      '@type': 'Person',
-      name: comment.author.name,
-      image: comment.author.gravatarUrl,
-      url: comment.author.url,
-    },
-    creator: {
-      '@type': 'Person',
-      name: comment.author.name,
-      image: comment.author.gravatarUrl,
-      url: comment.author.url,
-    },
-    dateCreated: comment.date,
-    datePublished: comment.date,
-    text: comment.content,
-  };
-
-  return (
-    <>
-      <Script
-        id="schema-comments"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      <li className={styles.item}>
-        {comment.approved ? getApprovedComment() : getCommentStatus()}
-      </li>
-    </>
-  );
-};
-
-export default Comment;
diff --git a/src/components/CommentForm/CommentForm.module.scss b/src/components/CommentForm/CommentForm.module.scss
deleted file mode 100644
index d19a1ef..0000000
--- a/src/components/CommentForm/CommentForm.module.scss
+++ /dev/null
@@ -1,25 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.wrapper {
-  width: min(calc(100vw - (var(--spacing-md) * 2)), fun.convert-px(500));
-  margin: auto;
-
-  &--reply {
-    width: 100%;
-    margin-top: var(--spacing-sm);
-    padding: var(--spacing-md);
-    position: relative;
-    background: var(--color-bg);
-    border: fun.convert-px(1) solid var(--color-border);
-    box-shadow: fun.convert-px(3) fun.convert-px(3) 0 0
-        var(--color-shadow-light),
-      fun.convert-px(4) fun.convert-px(4) fun.convert-px(3) fun.convert-px(-2)
-        var(--color-shadow);
-  }
-}
-
-.title {
-  width: max-content;
-  margin-left: auto;
-  margin-right: auto;
-}
diff --git a/src/components/CommentForm/CommentForm.tsx b/src/components/CommentForm/CommentForm.tsx
deleted file mode 100644
index 128dc58..0000000
--- a/src/components/CommentForm/CommentForm.tsx
+++ /dev/null
@@ -1,240 +0,0 @@
-import { ButtonSubmit } from '@components/Buttons';
-import { Field, Form, FormItem, Label } from '@components/FormElements';
-import Notice from '@components/Notice/Notice';
-import Spinner from '@components/Spinner/Spinner';
-import { createComment } from '@services/graphql/mutations';
-import { NoticeType } from '@ts/types/app';
-import { useEffect, useRef, useState } from 'react';
-import { useIntl } from 'react-intl';
-import styles from './CommentForm.module.scss';
-
-const CommentForm = ({
-  articleId,
-  parentId = 0,
-}: {
-  articleId: number;
-  parentId?: number;
-}) => {
-  const intl = useIntl();
-  const [name, setName] = useState<string>('');
-  const [email, setEmail] = useState<string>('');
-  const [website, setWebsite] = useState<string>('');
-  const [comment, setComment] = useState<string>('');
-  const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
-  const [notice, setNotice] = useState<string>();
-  const [noticeType, setNoticeType] = useState<NoticeType>('success');
-  const nameFieldRef = useRef<HTMLInputElement>(null);
-
-  useEffect(() => {
-    if (parentId === 0) return;
-    nameFieldRef.current && nameFieldRef.current.focus();
-  });
-
-  const resetForm = () => {
-    setName('');
-    setEmail('');
-    setWebsite('');
-    setComment('');
-    setIsSubmitting(false);
-  };
-
-  const isEmptyString = (value: string): boolean => value.trim() === '';
-  const areRequiredFieldsSet = (): boolean =>
-    !isEmptyString(name) && !isEmptyString(email) && !isEmptyString(comment);
-
-  const sendComment = async () => {
-    const data = {
-      author: name,
-      authorEmail: email,
-      authorUrl: website,
-      content: comment,
-      parent: parentId,
-      commentOn: articleId,
-      mutationId: 'createComment',
-    };
-
-    const createdComment = await createComment(data);
-
-    if (createdComment.success) {
-      resetForm();
-      setNoticeType('success');
-      if (createdComment.comment?.approved) {
-        setNotice(
-          intl.formatMessage({
-            defaultMessage: 'Thanks for your comment!',
-            description: 'CommentForm: success notice',
-            id: 'AVUUgG',
-          })
-        );
-      } else {
-        setNotice(
-          intl.formatMessage({
-            defaultMessage:
-              'Thanks for your comment! It is now awaiting moderation.',
-            description: 'CommentForm: success notice but awaiting moderation',
-            id: 'Ul2NIl',
-          })
-        );
-      }
-
-      setTimeout(() => {
-        setNotice(undefined);
-      }, 10000);
-    } else {
-      setNoticeType('error');
-      setNotice(
-        intl.formatMessage({
-          defaultMessage:
-            'An unexpected error happened. Comment cannot be submitted.',
-          description: 'CommentForm: error notice',
-          id: 'cjK9Ad',
-        })
-      );
-    }
-  };
-
-  const submitHandler = async (e: SubmitEvent) => {
-    e.preventDefault();
-    setNotice(undefined);
-    setIsSubmitting(true);
-
-    if (areRequiredFieldsSet()) {
-      sendComment();
-    } else {
-      setIsSubmitting(false);
-      setNoticeType('warning');
-      setNotice(
-        intl.formatMessage({
-          defaultMessage:
-            'Some required fields are empty. Comment cannot be submitted.',
-          description: 'CommentForm: missing required fields',
-          id: 'Rle+UK',
-        })
-      );
-    }
-  };
-
-  const isReply = parentId !== 0;
-  const wrapperClasses = `${styles.wrapper} ${
-    isReply ? styles['wrapper--reply'] : ''
-  }`;
-
-  const getLabel = (
-    body: string,
-    htmlFor: string,
-    required: boolean = false
-  ) => {
-    return <Label body={body} htmlFor={htmlFor} required={required} />;
-  };
-
-  const nameLabelBody = intl.formatMessage({
-    defaultMessage: 'Name',
-    description: 'CommentForm: Name field label',
-    id: 'F7QxJH',
-  });
-
-  const emailLabelBody = intl.formatMessage({
-    defaultMessage: 'Email',
-    description: 'CommentForm: Email field label',
-    id: 'Oim3rQ',
-  });
-
-  const websiteLabelBody = intl.formatMessage({
-    defaultMessage: 'Website',
-    description: 'CommentForm: Website field label',
-    id: 'jN+dY5',
-  });
-
-  const commentLabelBody = intl.formatMessage({
-    defaultMessage: 'Comment',
-    description: 'CommentForm: Comment field label',
-    id: 'J4nhm4',
-  });
-
-  return (
-    <div className={wrapperClasses}>
-      <h2 className={styles.title}>
-        {intl.formatMessage({
-          defaultMessage: 'Leave a comment',
-          description: 'CommentForm: Form title',
-          id: '+aHn7j',
-        })}
-      </h2>
-      <Form
-        submitHandler={submitHandler}
-        kind={isReply ? 'centered' : undefined}
-      >
-        <FormItem>
-          <Field
-            id="commenter-name"
-            name="commenter-name"
-            label={getLabel(nameLabelBody, 'commenter-name', true)}
-            value={name}
-            setValue={setName}
-            required={true}
-            ref={nameFieldRef}
-          />
-        </FormItem>
-        <FormItem>
-          <Field
-            id="commenter-email"
-            name="commenter-email"
-            kind="email"
-            label={getLabel(emailLabelBody, 'commenter-email', true)}
-            value={email}
-            setValue={setEmail}
-            required={true}
-          />
-        </FormItem>
-        <FormItem>
-          <Field
-            id="commenter-website"
-            name="commenter-website"
-            label={getLabel(websiteLabelBody, 'commenter-website')}
-            value={website}
-            setValue={setWebsite}
-          />
-        </FormItem>
-        <FormItem>
-          <Field
-            id="commenter-comment"
-            name="commenter-comment"
-            kind="textarea"
-            label={getLabel(commentLabelBody, 'commenter-comment', true)}
-            value={comment}
-            setValue={setComment}
-            required={true}
-          />
-        </FormItem>
-        <FormItem>
-          <noscript>
-            {intl.formatMessage({
-              defaultMessage: 'Javascript is required to post a comment.',
-              description: 'CommentForm: noscript tag',
-              id: 'g1cFCa',
-            })}
-          </noscript>
-          <ButtonSubmit>
-            {intl.formatMessage({
-              defaultMessage: 'Send',
-              description: 'CommentForm: Send button',
-              id: 'WGFOmA',
-            })}
-          </ButtonSubmit>
-        </FormItem>
-      </Form>
-      {isSubmitting && (
-        <Spinner
-          message={intl.formatMessage({
-            defaultMessage: 'Submitting...',
-            description: 'CommentForm: submitting message',
-            id: 'HEJ3Gv',
-          })}
-        />
-      )}
-      {notice && <Notice type={noticeType}>{notice}</Notice>}
-    </div>
-  );
-};
-
-export default CommentForm;
diff --git a/src/components/CommentsList/CommentsList.module.scss b/src/components/CommentsList/CommentsList.module.scss
deleted file mode 100644
index 4971b15..0000000
--- a/src/components/CommentsList/CommentsList.module.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-@use "@styles/abstracts/placeholders";
-
-.title,
-.no-comments {
-  width: max-content;
-  margin-left: auto;
-  margin-right: auto;
-}
-
-.list {
-  @extend %reset-ordered-list;
-
-  margin-bottom: var(--spacing-lg);
-}
diff --git a/src/components/CommentsList/CommentsList.tsx b/src/components/CommentsList/CommentsList.tsx
deleted file mode 100644
index 0eaac17..0000000
--- a/src/components/CommentsList/CommentsList.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-import Comment from '@components/Comment/Comment';
-import Spinner from '@components/Spinner/Spinner';
-import { getCommentsByPostId } from '@services/graphql/queries';
-import { Comment as CommentData } from '@ts/types/comments';
-import { useIntl } from 'react-intl';
-import useSWR from 'swr';
-import styles from './CommentsList.module.scss';
-
-const CommentsList = ({
-  articleId,
-  comments,
-}: {
-  articleId: number;
-  comments: CommentData[];
-}) => {
-  const intl = useIntl();
-  const { data, error } = useSWR<CommentData[]>(
-    '/api/comments',
-    () => getCommentsByPostId(articleId),
-    { fallbackData: comments }
-  );
-
-  const getCommentsList = () => {
-    if (error) {
-      return intl.formatMessage({
-        defaultMessage: 'Failed to load.',
-        description: 'CommentsList: failed to load',
-        id: 'Zlkww3',
-      });
-    }
-
-    if (!data) return <Spinner />;
-
-    return data.map((comment) => {
-      return (
-        <Comment
-          key={comment.databaseId}
-          articleId={articleId}
-          comment={comment}
-        />
-      );
-    });
-  };
-
-  return (
-    <>
-      <h2 className={styles.title}>
-        {intl.formatMessage({
-          defaultMessage: 'Comments',
-          description: 'CommentsList: Comments section title',
-          id: 'Ns8CFb',
-        })}
-      </h2>
-      {data && data.length > 0 ? (
-        <ol className={styles.list}>{getCommentsList()}</ol>
-      ) : (
-        <p className={styles['no-comments']}>
-          {intl.formatMessage({
-            defaultMessage: 'No comments yet.',
-            description: 'CommentsList: No comment message',
-            id: 'e9L59q',
-          })}
-        </p>
-      )}
-    </>
-  );
-};
-
-export default CommentsList;
diff --git a/src/components/ContactForm/ContactForm.module.scss b/src/components/ContactForm/ContactForm.module.scss
deleted file mode 100644
index 3f0e861..0000000
--- a/src/components/ContactForm/ContactForm.module.scss
+++ /dev/null
@@ -1,21 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.status {
-  max-width: max-content;
-  margin: var(--spacing-md) 0;
-  padding: var(--spacing-sm);
-  border: fun.convert-px(3) solid var(--color-border-light);
-  border-radius: fun.convert-px(5);
-
-  &--error {
-    border-color: var(--color-token-red);
-  }
-
-  &--success {
-    border-color: var(--color-token-green);
-  }
-
-  &--warning {
-    border-color: var(--color-token-orange);
-  }
-}
diff --git a/src/components/ContactForm/ContactForm.tsx b/src/components/ContactForm/ContactForm.tsx
deleted file mode 100644
index 5af6982..0000000
--- a/src/components/ContactForm/ContactForm.tsx
+++ /dev/null
@@ -1,180 +0,0 @@
-import { ButtonSubmit } from '@components/Buttons';
-import { Field, Form, FormItem, Label } from '@components/FormElements';
-import { sendMail } from '@services/graphql/mutations';
-import { settings } from '@utils/config';
-import { FormEvent, useState } from 'react';
-import { useIntl } from 'react-intl';
-import styles from './ContactForm.module.scss';
-
-type Status = 'success' | 'error' | 'warning';
-
-const ContactForm = () => {
-  const intl = useIntl();
-  const [name, setName] = useState('');
-  const [email, setEmail] = useState('');
-  const [subject, setSubject] = useState('');
-  const [message, setMessage] = useState('');
-  const [status, setStatus] = useState<Status>();
-  const [statusMessage, setStatusMessage] = useState<string>('');
-
-  const resetForm = () => {
-    setName('');
-    setEmail('');
-    setSubject('');
-    setMessage('');
-  };
-
-  const submitHandler = async (e: FormEvent) => {
-    e.preventDefault();
-
-    if (!name || !email || !message) {
-      setStatus('warning');
-      setStatusMessage(
-        intl.formatMessage({
-          defaultMessage:
-            'Warning: mail not sent. Some required fields are empty.',
-          description: 'ContactForm: missing fields message.',
-          id: 'WpycgB',
-        })
-      );
-      return;
-    }
-
-    const messageHTML = message.replace(/\r?\n/g, '<br />');
-    const body = `Message received from ${name} <${email}> on ${settings.url}.<br /><br />${messageHTML}`;
-    const replyTo = `${name} <${email}>`;
-    const data = {
-      body,
-      mutationId: 'contact',
-      replyTo,
-      subject,
-    };
-    const mail = await sendMail(data);
-
-    if (mail.sent) {
-      setStatus('success');
-      setStatusMessage(
-        intl.formatMessage({
-          defaultMessage:
-            'Thanks. Your message was successfully sent. I will answer it as soon as possible.',
-          description: 'ContactForm: success message',
-          id: 'gQKeF+',
-        })
-      );
-      resetForm();
-    } else {
-      const errorPrefix = intl.formatMessage({
-        defaultMessage: 'An error occurred:',
-        description: 'ContactForm: error message',
-        id: 'pTxT7N',
-      });
-      const error = `${errorPrefix} ${mail.message}`;
-      setStatus('error');
-      setStatusMessage(error);
-    }
-  };
-
-  const getStatus = () => {
-    if (!status) return <></>;
-
-    const statusModifier = `status--${status}`;
-
-    return (
-      <p className={`${styles.status} ${styles[statusModifier]}`}>
-        {statusMessage}
-      </p>
-    );
-  };
-
-  const getLabel = (
-    body: string,
-    htmlFor: string,
-    required: boolean = false
-  ) => {
-    return <Label body={body} htmlFor={htmlFor} required={required} />;
-  };
-
-  const nameLabelBody = intl.formatMessage({
-    defaultMessage: 'Name',
-    description: 'ContactForm: name field label',
-    id: '6ibqFS',
-  });
-
-  const emailLabelBody = intl.formatMessage({
-    defaultMessage: 'Email',
-    description: 'ContactForm: email field label',
-    id: 'Vuryko',
-  });
-
-  const subjectLabelBody = intl.formatMessage({
-    defaultMessage: 'Subject',
-    description: 'ContactForm: subject field label',
-    id: 'uMURuJ',
-  });
-
-  const messageLabelBody = intl.formatMessage({
-    defaultMessage: 'Message',
-    description: 'ContactForm: message field label',
-    id: '0zBQpa',
-  });
-
-  return (
-    <>
-      <Form submitHandler={submitHandler}>
-        <FormItem>
-          <Field
-            id="contact-name"
-            name="name"
-            value={name}
-            setValue={setName}
-            required={true}
-            label={getLabel(nameLabelBody, 'contact-name', true)}
-          />
-        </FormItem>
-        <FormItem>
-          <Field
-            id="contact-email"
-            kind="email"
-            name="email"
-            value={email}
-            setValue={setEmail}
-            required={true}
-            label={getLabel(emailLabelBody, 'contact-email', true)}
-          />
-        </FormItem>
-        <FormItem>
-          <Field
-            id="contact-subject"
-            name="subject"
-            value={subject}
-            setValue={setSubject}
-            label={getLabel(subjectLabelBody, 'contact-subject')}
-          />
-        </FormItem>
-        <FormItem>
-          <Field
-            id="contact-message"
-            kind="textarea"
-            name="message"
-            value={message}
-            setValue={setMessage}
-            required={true}
-            label={getLabel(messageLabelBody, 'contact-message', true)}
-          />
-        </FormItem>
-        <FormItem>
-          <ButtonSubmit>
-            {intl.formatMessage({
-              defaultMessage: 'Send',
-              description: 'ContactForm: send button text',
-              id: 'X7n7N2',
-            })}
-          </ButtonSubmit>
-        </FormItem>
-      </Form>
-      {getStatus()}
-    </>
-  );
-};
-
-export default ContactForm;
diff --git a/src/components/Copyright/Copyright.module.scss b/src/components/Copyright/Copyright.module.scss
deleted file mode 100644
index 35445b2..0000000
--- a/src/components/Copyright/Copyright.module.scss
+++ /dev/null
@@ -1,33 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-
-.wrapper {
-  --icon-size: #{fun.convert-px(70)};
-
-  display: flex;
-  flex-flow: row wrap;
-  align-items: center;
-  place-content: center;
-  gap: var(--spacing-2xs);
-  margin: 0;
-  font-family: var(--font-family-secondary);
-  font-size: var(--font-size-md);
-  text-align: center;
-
-  @include mix.media("screen") {
-    @include mix.dimensions("sm") {
-      place-content: start;
-      text-align: left;
-    }
-  }
-}
-
-.name {
-  flex: 1 0 100%;
-
-  @include mix.media("screen") {
-    @include mix.dimensions("sm") {
-      flex: auto;
-    }
-  }
-}
diff --git a/src/components/Copyright/Copyright.tsx b/src/components/Copyright/Copyright.tsx
deleted file mode 100644
index d2de2e9..0000000
--- a/src/components/Copyright/Copyright.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import { CopyrightIcon } from '@components/Icons';
-import { settings } from '@utils/config';
-import styles from './Copyright.module.scss';
-
-const Copyright = () => {
-  return (
-    <p className={styles.wrapper}>
-      <span className={styles.name}>{settings.name}</span>
-      <CopyrightIcon />
-      <span>
-        {settings.copyright.startYear} - {settings.copyright.endYear}
-      </span>
-    </p>
-  );
-};
-
-export default Copyright;
diff --git a/src/components/Footer/Footer.module.scss b/src/components/Footer/Footer.module.scss
deleted file mode 100644
index 1d156f8..0000000
--- a/src/components/Footer/Footer.module.scss
+++ /dev/null
@@ -1,90 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-
-.wrapper {
-  display: flex;
-  flex-flow: column wrap;
-  gap: var(--spacing-xs);
-  place-items: center;
-  place-content: center;
-  padding: var(--spacing-md) 0 calc(var(--toolbar-size) + var(--spacing-md));
-  border-top: fun.convert-px(3) solid var(--color-border-light);
-
-  @include mix.media("screen") {
-    @include mix.dimensions("sm") {
-      flex-flow: row wrap;
-      font-size: var(--font-size-sm);
-    }
-  }
-}
-
-.back-to-top {
-  --button-size: #{fun.convert-px(55)};
-  --icon-size: #{fun.convert-px(32)};
-
-  position: fixed;
-  bottom: calc(var(--toolbar-size) + var(--spacing-md));
-  right: var(--spacing-md);
-  transition: all 0.4s ease-in 0s;
-
-  &--hidden {
-    opacity: 0;
-    transform: translateY(calc(var(--button-size) + var(--spacing-md)));
-  }
-
-  &--visible {
-    opacity: 1;
-    transform: translateY(0);
-  }
-
-  a {
-    display: flex;
-    place-content: center;
-    padding: 0;
-    width: var(--button-size);
-    height: var(--button-size);
-
-    svg {
-      height: 85%;
-    }
-
-    :global {
-      .arrow-head {
-        transform: translateY(30%);
-        transition: all 0.45s ease-in-out 0s;
-      }
-
-      .arrow-bar {
-        opacity: 0;
-        transform: translateY(30%) translateX(25%) scale(0.5);
-        transition: transform 0.45s ease-in-out 0s, opacity 0.3s ease-in-out 0s;
-      }
-    }
-
-    &:hover,
-    &:focus {
-      :global {
-        .arrow-head {
-          transform: translateY(0);
-        }
-
-        .arrow-bar {
-          opacity: 1;
-          transform: translateY(0) translateX(0) scale(1);
-        }
-      }
-
-      svg {
-        :global {
-          animation: pulse 1.2s ease-in-out 0.6s infinite;
-        }
-      }
-    }
-
-    &:active {
-      svg {
-        animation-play-state: paused;
-      }
-    }
-  }
-}
diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx
deleted file mode 100644
index 381b4a8..0000000
--- a/src/components/Footer/Footer.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import { ButtonLink } from '@components/Buttons';
-import Copyright from '@components/Copyright/Copyright';
-import FooterNav from '@components/FooterNav/FooterNav';
-import { ArrowIcon } from '@components/Icons';
-import { useEffect, useState } from 'react';
-import { useIntl } from 'react-intl';
-import styles from './Footer.module.scss';
-
-const Footer = () => {
-  const intl = useIntl();
-  const [backToTopClasses, setBackToTopClasses] = useState(
-    `${styles['back-to-top']} ${styles['back-to-top--hidden']}`
-  );
-
-  const handleScroll = () => {
-    const currentScrollY = window.scrollY;
-
-    if (currentScrollY > 300) {
-      setBackToTopClasses(
-        `${styles['back-to-top']} ${styles['back-to-top--visible']}`
-      );
-    } else {
-      setBackToTopClasses(
-        `${styles['back-to-top']} ${styles['back-to-top--hidden']}`
-      );
-    }
-  };
-
-  useEffect(() => {
-    window.addEventListener('scroll', handleScroll);
-    return () => window.removeEventListener('scroll', handleScroll);
-  }, []);
-
-  return (
-    <footer className={styles.wrapper}>
-      <Copyright />
-      <FooterNav />
-      <div className={backToTopClasses}>
-        <ButtonLink target="#top" position="center">
-          <span className="screen-reader-text">
-            {intl.formatMessage({
-              defaultMessage: 'Back to top',
-              description: 'Footer: Back to top button',
-              id: 'dqrd6I',
-            })}
-          </span>
-          <ArrowIcon direction="top" />
-        </ButtonLink>
-      </div>
-    </footer>
-  );
-};
-
-export default Footer;
diff --git a/src/components/FooterNav/FooterNav.module.scss b/src/components/FooterNav/FooterNav.module.scss
deleted file mode 100644
index 73ea568..0000000
--- a/src/components/FooterNav/FooterNav.module.scss
+++ /dev/null
@@ -1,20 +0,0 @@
-@use "@styles/abstracts/mixins" as mix;
-@use "@styles/abstracts/placeholders";
-
-.list {
-  @extend %flex-list;
-
-  gap: var(--spacing-xs);
-  place-content: center;
-}
-
-.item {
-  @include mix.media("screen") {
-    @include mix.dimensions("sm") {
-      &::before {
-        content: "\2022";
-        margin-right: var(--spacing-xs);
-      }
-    }
-  }
-}
diff --git a/src/components/FooterNav/FooterNav.tsx b/src/components/FooterNav/FooterNav.tsx
deleted file mode 100644
index 763e951..0000000
--- a/src/components/FooterNav/FooterNav.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import Link from 'next/link';
-import styles from './FooterNav.module.scss';
-import { NavItem } from '@ts/types/nav';
-import { useIntl } from 'react-intl';
-
-const FooterNav = () => {
-  const intl = useIntl();
-
-  const footerNavConfig: NavItem[] = [
-    {
-      id: 'legal-notice',
-      name: intl.formatMessage({
-        defaultMessage: 'Legal notice',
-        description: 'FooterNav: legal notice link',
-        id: 'yWjXRx',
-      }),
-      slug: '/mentions-legales',
-    },
-  ];
-
-  const navItems = footerNavConfig.map((item) => {
-    return (
-      <li key={item.id} className={styles.item}>
-        <Link href={item.slug}>
-          <a className={styles.link}>{item.name}</a>
-        </Link>
-      </li>
-    );
-  });
-
-  return (
-    <nav
-      className={styles.nav}
-      aria-label={intl.formatMessage({
-        defaultMessage: 'Footer',
-        description: 'FooterNav: aria-label',
-        id: 'HTdaZj',
-      })}
-    >
-      <ul className={styles.list}>{navItems}</ul>
-    </nav>
-  );
-};
-
-export default FooterNav;
diff --git a/src/components/FormElements/Field/Field.module.scss b/src/components/FormElements/Field/Field.module.scss
deleted file mode 100644
index 9100495..0000000
--- a/src/components/FormElements/Field/Field.module.scss
+++ /dev/null
@@ -1,53 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-
-.field {
-  background: var(--color-bg-tertiary);
-  border: fun.convert-px(2) solid var(--color-border);
-  box-shadow: fun.convert-px(3) fun.convert-px(3) 0 0 var(--color-shadow);
-  transition: all 0.25s linear 0s;
-
-  &:not(.select) {
-    width: 100%;
-    padding: var(--spacing-2xs) var(--spacing-xs);
-  }
-
-  &:hover {
-    box-shadow: fun.convert-px(5) fun.convert-px(5) 0 fun.convert-px(1)
-      var(--color-shadow);
-    transform: translate(#{fun.convert-px(-3)}, #{fun.convert-px(-3)});
-  }
-
-  &:focus {
-    background: var(--color-bg);
-    border-color: var(--color-primary);
-    box-shadow: 0 0 0 0 var(--color-shadow);
-    transform: translate(#{fun.convert-px(3)}, #{fun.convert-px(3)});
-    outline: none;
-    transition: all 0.2s ease-in-out 0s, transform 0.3s ease-out 0s;
-  }
-}
-
-.select {
-  padding: var(--spacing-2xs) var(--spacing-xs);
-  cursor: pointer;
-
-  @include mix.pointer("fine") {
-    padding: fun.convert-px(3) var(--spacing-xs);
-  }
-
-  &:hover {
-    box-shadow: fun.convert-px(4) fun.convert-px(4) 0 fun.convert-px(1)
-      var(--color-shadow);
-    transform: translate(#{fun.convert-px(-2)}, #{fun.convert-px(-2)});
-  }
-
-  &:focus {
-    box-shadow: 0 0 0 0 var(--color-shadow);
-    transform: translate(#{fun.convert-px(3)}, #{fun.convert-px(3)});
-  }
-}
-
-.textarea {
-  min-height: fun.convert-px(200);
-}
diff --git a/src/components/FormElements/Field/Field.tsx b/src/components/FormElements/Field/Field.tsx
deleted file mode 100644
index c8df0f9..0000000
--- a/src/components/FormElements/Field/Field.tsx
+++ /dev/null
@@ -1,106 +0,0 @@
-import {
-  ChangeEvent,
-  ForwardedRef,
-  forwardRef,
-  ReactElement,
-  SetStateAction,
-} from 'react';
-import styles from './Field.module.scss';
-
-type FieldType = 'email' | 'number' | 'search' | 'select' | 'text' | 'textarea';
-type SelectOptions = {
-  id: string;
-  name: string;
-  value: string;
-};
-
-const Field = (
-  {
-    id,
-    name,
-    value,
-    setValue,
-    required = false,
-    kind = 'text',
-    label,
-    options,
-  }: {
-    id: string;
-    name: string;
-    value: string;
-    setValue: (value: SetStateAction<string>) => void;
-    required?: boolean;
-    kind?: FieldType;
-    label?: ReactElement;
-    options?: SelectOptions[];
-  },
-  ref: ForwardedRef<HTMLInputElement | HTMLTextAreaElement>
-) => {
-  const updateValue = (
-    e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>
-  ) => {
-    setValue(e.target.value);
-  };
-
-  const getOptions = () => {
-    return options
-      ? options.map((option) => (
-          <option key={option.id} value={option.value}>
-            {option.name}
-          </option>
-        ))
-      : '';
-  };
-
-  const getField = () => {
-    switch (kind) {
-      case 'select':
-        return (
-          <select
-            name={name}
-            id={id}
-            value={value}
-            onChange={updateValue}
-            required={required}
-            className={`${styles.field} ${styles.select}`}
-          >
-            {getOptions()}
-          </select>
-        );
-      case 'textarea':
-        return (
-          <textarea
-            ref={ref as ForwardedRef<HTMLTextAreaElement>}
-            id={id}
-            name={name}
-            value={value}
-            required={required}
-            onChange={updateValue}
-            className={`${styles.field} ${styles.textarea}`}
-          />
-        );
-      default:
-        return (
-          <input
-            ref={ref as ForwardedRef<HTMLInputElement>}
-            type={kind}
-            id={id}
-            name={name}
-            value={value}
-            required={required}
-            onChange={updateValue}
-            className={styles.field}
-          />
-        );
-    }
-  };
-
-  return (
-    <>
-      {label}
-      {getField()}
-    </>
-  );
-};
-
-export default forwardRef(Field);
diff --git a/src/components/FormElements/Form/Form.module.scss b/src/components/FormElements/Form/Form.module.scss
deleted file mode 100644
index 0f7c437..0000000
--- a/src/components/FormElements/Form/Form.module.scss
+++ /dev/null
@@ -1,37 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.wrapper {
-  width: 100%;
-}
-
-.centered {
-  max-width: 45ch;
-  margin-left: auto;
-  margin-right: auto;
-}
-
-.search {
-  display: flex;
-  flex-flow: row nowrap;
-  align-items: center;
-
-  > input {
-    padding-right: calc(var(--btn-size) + var(--spacing-2xs));
-
-    &:hover ~ button {
-      transform: translate(fun.convert-px(-3), fun.convert-px(-3));
-    }
-
-    &:focus ~ button {
-      transform: translate(fun.convert-px(3), fun.convert-px(3));
-    }
-  }
-}
-
-.settings {
-  display: flex;
-  flex-flow: row nowrap;
-  align-items: center;
-  margin: var(--spacing-sm) 0;
-  position: relative;
-}
diff --git a/src/components/FormElements/Form/Form.tsx b/src/components/FormElements/Form/Form.tsx
deleted file mode 100644
index 10fdcdf..0000000
--- a/src/components/FormElements/Form/Form.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { ReactNode } from 'react';
-import styles from './Form.module.scss';
-
-type FormKind = 'centered' | 'search' | 'settings';
-
-const Form = ({
-  children,
-  submitHandler,
-  kind,
-  id,
-}: {
-  children: ReactNode;
-  submitHandler: any;
-  kind?: FormKind;
-  id?: string;
-}) => {
-  const kindStyles = kind ? styles[kind] : '';
-  const classes = `${styles.wrapper} ${kindStyles}`;
-
-  return (
-    <form onSubmit={submitHandler} className={classes} id={id}>
-      {children}
-    </form>
-  );
-};
-
-export default Form;
diff --git a/src/components/FormElements/FormItem/FormItem.module.scss b/src/components/FormElements/FormItem/FormItem.module.scss
deleted file mode 100644
index 07ef56f..0000000
--- a/src/components/FormElements/FormItem/FormItem.module.scss
+++ /dev/null
@@ -1,4 +0,0 @@
-.wrapper {
-  margin: var(--spacing-xs) 0;
-  max-width: 45ch;
-}
diff --git a/src/components/FormElements/FormItem/FormItem.tsx b/src/components/FormElements/FormItem/FormItem.tsx
deleted file mode 100644
index 8d674f1..0000000
--- a/src/components/FormElements/FormItem/FormItem.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import styles from './FormItem.module.scss';
-
-const FormItem: React.FunctionComponent = ({ children }) => {
-  return <div className={styles.wrapper}>{children}</div>;
-};
-
-export default FormItem;
diff --git a/src/components/FormElements/Label/Label.module.scss b/src/components/FormElements/Label/Label.module.scss
deleted file mode 100644
index c527b16..0000000
--- a/src/components/FormElements/Label/Label.module.scss
+++ /dev/null
@@ -1,22 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.regular {
-  display: block;
-  color: var(--color-primary-darker);
-  font-size: var(--font-size-sm);
-  font-variant: small-caps;
-  font-weight: 600;
-}
-
-.settings {
-  --icon-size: #{fun.convert-px(25)};
-  --toggle-width: #{fun.convert-px(45)};
-  --toggle-height: calc(var(--toggle-width) / 2);
-
-  display: inline-flex;
-  align-items: center;
-}
-
-.required {
-  color: var(--color-secondary);
-}
diff --git a/src/components/FormElements/Label/Label.tsx b/src/components/FormElements/Label/Label.tsx
deleted file mode 100644
index baedff0..0000000
--- a/src/components/FormElements/Label/Label.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import styles from './Label.module.scss';
-
-type LabelKind = 'regular' | 'settings';
-
-const Label = ({
-  body,
-  htmlFor,
-  required = false,
-  kind = 'regular',
-}: {
-  body: string;
-  htmlFor: string;
-  required?: boolean;
-  kind?: LabelKind;
-}) => {
-  return (
-    <label htmlFor={htmlFor} className={styles[kind]}>
-      {body}
-      {required && <span className={styles.required}> *</span>}
-    </label>
-  );
-};
-
-export default Label;
diff --git a/src/components/FormElements/Toggle/Toggle.module.scss b/src/components/FormElements/Toggle/Toggle.module.scss
deleted file mode 100644
index 48c88f6..0000000
--- a/src/components/FormElements/Toggle/Toggle.module.scss
+++ /dev/null
@@ -1,75 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.label {
-  --icon-size: #{fun.convert-px(25)};
-  --toggle-width: #{fun.convert-px(45)};
-  --toggle-height: calc(var(--toggle-width) / 2);
-
-  display: inline-flex;
-  align-items: center;
-}
-
-.title {
-  margin-right: var(--spacing-xs);
-}
-
-.toggle {
-  display: inline-flex;
-  align-items: center;
-  width: var(--toggle-width);
-  height: var(--toggle-height);
-  background: var(--color-shadow-light);
-  border: fun.convert-px(1) solid var(--color-primary);
-  border-radius: fun.convert-px(32);
-  box-shadow: inset 0 0 fun.convert-px(3) 0 var(--color-shadow-dark);
-  margin: 0 var(--spacing-2xs);
-  position: relative;
-
-  &::after {
-    content: "";
-    display: block;
-    width: calc(var(--toggle-width) / 2);
-    height: calc(var(--toggle-width) / 2);
-    background: var(--color-primary-light);
-    border: fun.convert-px(1) solid var(--color-primary);
-    border-radius: 50%;
-    box-shadow: inset 0 0 fun.convert-px(1) fun.convert-px(1)
-        var(--color-shadow),
-      0 0 fun.convert-px(2) fun.convert-px(1) var(--color-shadow-light);
-    position: absolute;
-    left: fun.convert-px(-2);
-    transition: all 0.3s ease-in-out 0s;
-  }
-}
-
-.checkbox {
-  position: absolute;
-  opacity: 0;
-  cursor: pointer;
-
-  &:checked ~ .label {
-    .toggle::after {
-      position: absolute;
-      left: calc(100% - (var(--toggle-width) / 2) + #{fun.convert-px(2)});
-    }
-  }
-
-  &:hover,
-  &:focus {
-    ~ .label {
-      .toggle::after {
-        background: var(--color-primary-lighter);
-      }
-    }
-  }
-
-  &:focus ~ .label {
-    .title {
-      text-decoration: underline solid var(--color-primary) fun.convert-px(2);
-    }
-
-    .toggle {
-      outline: var(--color-border) solid fun.convert-px(5);
-    }
-  }
-}
diff --git a/src/components/FormElements/Toggle/Toggle.tsx b/src/components/FormElements/Toggle/Toggle.tsx
deleted file mode 100644
index 4db7d43..0000000
--- a/src/components/FormElements/Toggle/Toggle.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { FormEvent, ReactElement } from 'react';
-import { Form } from '..';
-import styles from './Toggle.module.scss';
-
-const Toggle = ({
-  id,
-  label,
-  value,
-  changeHandler,
-  leftChoice,
-  rightChoice,
-  name,
-}: {
-  id: string;
-  label: string;
-  value: boolean;
-  changeHandler: (value: boolean) => void;
-  leftChoice: ReactElement | string;
-  rightChoice: ReactElement | string;
-  name?: string;
-}) => {
-  const onSubmit = (e: FormEvent) => {
-    e.preventDefault();
-  };
-
-  return (
-    <Form kind="settings" submitHandler={onSubmit}>
-      <input
-        className={styles.checkbox}
-        type="checkbox"
-        id={id}
-        name={name ? name : id}
-        checked={value}
-        onChange={() => changeHandler(!value)}
-      />
-      <label htmlFor={id} className={styles.label}>
-        <span className={styles.title}>{label}</span>
-        {leftChoice}
-        <span className={styles.toggle}></span>
-        {rightChoice}
-      </label>
-    </Form>
-  );
-};
-
-export default Toggle;
diff --git a/src/components/FormElements/index.tsx b/src/components/FormElements/index.tsx
deleted file mode 100644
index 8ca69b4..0000000
--- a/src/components/FormElements/index.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import Field from './Field/Field';
-import Form from './Form/Form';
-import FormItem from './FormItem/FormItem';
-import Label from './Label/Label';
-import Toggle from './Toggle/Toggle';
-
-export { Field, Form, FormItem, Label, Toggle };
diff --git a/src/components/Header/Header.module.scss b/src/components/Header/Header.module.scss
deleted file mode 100644
index aa0d8cf..0000000
--- a/src/components/Header/Header.module.scss
+++ /dev/null
@@ -1,22 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.wrapper {
-  display: grid;
-  grid-template-columns:
-    minmax(0, 1fr) min(calc(100vw - calc(var(--spacing-md) * 2)), 100ch)
-    minmax(0, 1fr);
-  align-items: center;
-  padding: var(--spacing-sm) 0 var(--spacing-md);
-  position: relative;
-  background: var(--color-bg);
-  border-bottom: fun.convert-px(3) solid var(--color-border-light);
-}
-
-.body {
-  grid-column: 2;
-  display: flex;
-  flex-flow: row wrap;
-  align-items: center;
-  justify-content: space-between;
-  gap: var(--spacing-md);
-}
diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx
deleted file mode 100644
index 0b773e9..0000000
--- a/src/components/Header/Header.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import Branding from '@components/Branding/Branding';
-import Toolbar from '@components/Toolbar/Toolbar';
-import styles from './Header.module.scss';
-
-const Header = ({ isHome }: { isHome: boolean }) => {
-  return (
-    <header id="top" className={styles.wrapper}>
-      <div className={styles.body}>
-        <Branding isHome={isHome} />
-        <Toolbar />
-      </div>
-    </header>
-  );
-};
-
-export default Header;
diff --git a/src/components/Icons/Arrow/Arrow.module.scss b/src/components/Icons/Arrow/Arrow.module.scss
deleted file mode 100644
index 49e9b02..0000000
--- a/src/components/Icons/Arrow/Arrow.module.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.icon {
-  fill: var(--color-primary);
-  width: var(--icon-size, #{fun.convert-px(30)});
-  transition: all 0.25s ease-in-out 0s;
-}
diff --git a/src/components/Icons/Arrow/Arrow.tsx b/src/components/Icons/Arrow/Arrow.tsx
deleted file mode 100644
index e9131d1..0000000
--- a/src/components/Icons/Arrow/Arrow.tsx
+++ /dev/null
@@ -1,81 +0,0 @@
-import styles from './Arrow.module.scss';
-
-type ArrowDirection = 'top' | 'right' | 'bottom' | 'left';
-
-const ArrowIcon = ({ direction = 'right' }: { direction?: ArrowDirection }) => {
-  if (direction === 'top') {
-    return (
-      <svg
-        className={styles.icon}
-        viewBox="0 0 23.476 64.644995"
-        xmlns="http://www.w3.org/2000/svg"
-      >
-        <path
-          className="arrow-head"
-          d="M 23.476001,24.637 11.715001,0 0,24.800001 Z"
-        />
-        <path
-          className="arrow-bar"
-          d="m 15.441001,64.644997 -0.018,-40.007999 H 8.035 l 0.142,40.007999 z"
-        />
-      </svg>
-    );
-  }
-
-  if (direction === 'bottom') {
-    return (
-      <svg
-        className={styles.icon}
-        viewBox="0 0 23.476 64.644995"
-        xmlns="http://www.w3.org/2000/svg"
-      >
-        <path
-          className="arrow-head"
-          d="m 23.476001,40.007997 -11.761,24.637 L 0,39.844996 Z"
-        />
-        <path
-          className="arrow-bar"
-          d="m 15.441001,0 -0.018,40.007999 H 8.035 L 8.177,0 Z"
-        />
-      </svg>
-    );
-  }
-
-  if (direction === 'left') {
-    return (
-      <svg
-        className={styles.icon}
-        viewBox="0 0 64.644997 23.476001"
-        xmlns="http://www.w3.org/2000/svg"
-      >
-        <path
-          className="arrow-head"
-          d="M 24.637,23.476 0,11.715 24.8,-8.3923343e-8 Z"
-        />
-        <path
-          className="arrow-bar"
-          d="m 64.644997,15.441 -40.008,-0.018 V 8.0349999 l 40.008,0.142 z"
-        />
-      </svg>
-    );
-  }
-
-  return (
-    <svg
-      className={styles.icon}
-      viewBox="0 0 64.644997 23.476001"
-      xmlns="http://www.w3.org/2000/svg"
-    >
-      <path
-        className="arrow-head"
-        d="M 40.007997,23.476 64.644997,11.715 39.844997,-8.3923343e-8 Z"
-      />
-      <path
-        className="arrow-bar"
-        d="M 0,15.441 40.008,15.423 V 8.0349999 L 0,8.1769999 Z"
-      />
-    </svg>
-  );
-};
-
-export default ArrowIcon;
diff --git a/src/components/Icons/Blog/Blog.module.scss b/src/components/Icons/Blog/Blog.module.scss
deleted file mode 100644
index 5376c61..0000000
--- a/src/components/Icons/Blog/Blog.module.scss
+++ /dev/null
@@ -1,23 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.icon {
-  display: block;
-  margin: auto;
-  width: var(--icon-size, #{fun.convert-px(40)});
-}
-
-.lines {
-  fill: var(--color-fg);
-  stroke-width: 4;
-}
-
-.picture {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-darker);
-}
-
-.background {
-  fill: var(--color-bg);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-}
diff --git a/src/components/Icons/Blog/Blog.tsx b/src/components/Icons/Blog/Blog.tsx
deleted file mode 100644
index bd32111..0000000
--- a/src/components/Icons/Blog/Blog.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import styles from './Blog.module.scss';
-
-const BlogIcon = () => {
-  return (
-    <svg
-      viewBox="0 0 100 100"
-      xmlns="http://www.w3.org/2000/svg"
-      className={styles.icon}
-    >
-      <path
-        className={styles.background}
-        d="M 28.992096,1.4822128 H 90.770752 V 82.312253 H 28.992096 Z"
-      />
-      <path
-        className={styles.background}
-        d="m 19.110672,8.992094 h 61.778656 v 80.83004 H 19.110672 Z"
-      />
-      <path
-        className={styles.background}
-        d="m 9.229248,17.687748 h 61.778656 v 80.83004 H 9.229248 Z"
-      />
-      <path
-        className={styles.picture}
-        d="M 18.149242,74.65544 H 33.375246 V 90.194215 H 18.149242 Z"
-      />
-      <path
-        className={styles.picture}
-        d="M 18.142653,24.858688 H 62.094499 V 35.908926 H 18.142653 Z"
-      />
-      <path
-        className={styles.lines}
-        d="m 17.618576,41.908926 h 45 v 2 h -45 z"
-      />
-      <path
-        className={styles.lines}
-        d="m 17.618576,49.908926 h 45 v 2 h -45 z"
-      />
-      <path
-        className={styles.lines}
-        d="m 17.618576,57.908926 h 45 v 2 h -45 z"
-      />
-      <path
-        className={styles.lines}
-        d="m 17.618576,65.908926 h 45 v 2 h -45 z"
-      />
-      <path
-        className={styles.lines}
-        d="m 41.833105,73.424828 h 20.785471 v 2 H 41.833105 Z"
-      />
-      <path
-        className={styles.lines}
-        d="m 41.833105,81.424828 h 20.785471 v 2 H 41.833105 Z"
-      />
-      <path
-        className={styles.lines}
-        d="m 41.833105,89.424828 h 20.785471 v 2 H 41.833105 Z"
-      />
-    </svg>
-  );
-};
-
-export default BlogIcon;
diff --git a/src/components/Icons/CV/CV.module.scss b/src/components/Icons/CV/CV.module.scss
deleted file mode 100644
index aaa8a1a..0000000
--- a/src/components/Icons/CV/CV.module.scss
+++ /dev/null
@@ -1,54 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.icon {
-  display: block;
-  margin: auto;
-  width: var(--icon-size, #{fun.convert-px(40)});
-}
-
-.lock {
-  fill: var(--color-bg);
-  stroke: var(--color-primary-darker);
-  stroke-width: 3;
-}
-
-.lines {
-  fill: var(--color-fg);
-  stroke-width: 4;
-}
-
-.seal-top {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-darker);
-  stroke-width: 2;
-}
-
-.seal-bottom {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-darker);
-  stroke-width: 2;
-}
-
-.diploma {
-  fill: var(--color-bg);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-}
-
-.top {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-}
-
-.handle {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-darker);
-  stroke-width: 3;
-}
-
-.bottom {
-  fill: var(--color-primary);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-}
diff --git a/src/components/Icons/CV/CV.tsx b/src/components/Icons/CV/CV.tsx
deleted file mode 100644
index 876d1cb..0000000
--- a/src/components/Icons/CV/CV.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import styles from './CV.module.scss';
-
-const CVIcon = () => {
-  return (
-    <svg
-      viewBox="0 0 100 100"
-      xmlns="http://www.w3.org/2000/svg"
-      className={styles.icon}
-    >
-      <path
-        className={styles.bottom}
-        d="M 0.72670447,19.813041 H 77.467597 v 54.36591 H 0.72670447 Z"
-      />
-      <path
-        className={styles.handle}
-        d="m 22.263958,10.17849 c 12.6493,-1.81512 21.613185,-1.732794 33.666442,0 l 1.683339,10.99517 h -5.891624 v -5.474639 c -7.949741,-2.722434 -16.311959,-2.706359 -25.249837,0 v 5.474639 h -5.891625 z"
-      />
-      <path
-        className={styles.top}
-        d="M 0.72670447,19.813041 H 77.467597 V 51.17622 H 0.72670447 Z"
-      />
-      <path
-        className={styles.diploma}
-        d="M 44.217117,47.159906 H 98.921356 V 82.664122 H 44.217117 Z"
-      />
-      <path
-        className={styles['seal-bottom']}
-        d="m 84.933665,80.775336 h 6.957554 V 90.992144 L 88.412426,87.2244 84.933665,90.992144 Z"
-      />
-      <path
-        className={styles['seal-top']}
-        d="m 93.326919,76.83334 a 4.914472,4.9188584 0 0 1 -4.914493,4.918858 4.914472,4.9188584 0 0 1 -4.914461,-4.918858 4.914472,4.9188584 0 0 1 4.914461,-4.918858 4.914472,4.9188584 0 0 1 4.914493,4.918858 z"
-      />
-      <path
-        className={styles.lines}
-        d="m 54.53557,60.491974 h 34.067282 v 1.515453 H 54.53557 Z"
-      />
-      <path
-        className={styles.lines}
-        d="m 54.53557,67.437763 h 34.067282 v 1.515453 H 54.53557 Z"
-      />
-      <path
-        className={styles.lines}
-        d="m 54.53557,74.383628 h 17.563315 v 1.515454 H 54.53557 Z"
-      />
-      <path
-        className={styles.lines}
-        d="m 63.495911,53.546123 h 16.146628 v 1.515452 H 63.495911 Z"
-      />
-      <path
-        className={styles.lock}
-        d="M 34.048314,42.893007 H 44.145988 V 57.849688 H 34.048314 Z"
-      />
-    </svg>
-  );
-};
-
-export default CVIcon;
diff --git a/src/components/Icons/Close/Close.module.scss b/src/components/Icons/Close/Close.module.scss
deleted file mode 100644
index 5a1f638..0000000
--- a/src/components/Icons/Close/Close.module.scss
+++ /dev/null
@@ -1,13 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.icon {
-  display: block;
-  margin: auto;
-  width: var(--icon-size, #{fun.convert-px(40)});
-}
-
-.line {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-darker);
-  stroke-width: 3;
-}
diff --git a/src/components/Icons/Close/Close.tsx b/src/components/Icons/Close/Close.tsx
deleted file mode 100644
index 12214de..0000000
--- a/src/components/Icons/Close/Close.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import styles from './Close.module.scss';
-
-const CloseIcon = () => {
-  return (
-    <svg
-      viewBox="0 0 100 100"
-      xmlns="http://www.w3.org/2000/svg"
-      className={styles.icon}
-    >
-      <path
-        className={styles.line}
-        d="m 3.6465461,3.6465455 c 2.8785908,-2.87859092 7.5134339,-2.87859092 10.3920249,0 L 96.353457,85.96143 c 2.878587,2.878591 2.878587,7.513434 0,10.392025 -2.878597,2.878591 -7.513432,2.878591 -10.392029,0 L 3.6465451,14.038571 C 0.76795421,11.15998 0.76795421,6.5251364 3.6465461,3.6465455 Z"
-      />
-      <path
-        className={styles.line}
-        d="m 96.353453,3.646546 c 2.878592,2.8785909 2.878592,7.513435 0,10.392026 L 14.03857,96.353457 c -2.878589,2.878587 -7.5134337,2.878587 -10.3920246,0 -2.87859084,-2.878597 -2.87858985,-7.513442 -1e-6,-10.392029 L 85.961428,3.646546 c 2.878591,-2.87859097 7.513434,-2.87859097 10.392025,0 z"
-      />
-    </svg>
-  );
-};
-
-export default CloseIcon;
diff --git a/src/components/Icons/Cog/Cog.module.scss b/src/components/Icons/Cog/Cog.module.scss
deleted file mode 100644
index a861f0c..0000000
--- a/src/components/Icons/Cog/Cog.module.scss
+++ /dev/null
@@ -1,10 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.icon {
-  display: block;
-  width: var(--icon-size, #{fun.convert-px(40)});
-  margin: auto;
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-}
diff --git a/src/components/Icons/Cog/Cog.tsx b/src/components/Icons/Cog/Cog.tsx
deleted file mode 100644
index 7a04d76..0000000
--- a/src/components/Icons/Cog/Cog.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import styles from './Cog.module.scss';
-
-const CogIcon = () => {
-  return (
-    <svg
-      viewBox="0 0 100 100"
-      xmlns="http://www.w3.org/2000/svg"
-      className={styles.icon}
-    >
-      <path d="m 71.782287,3.1230469 c -1.164356,0 -2.3107,0.076326 -3.435131,0.2227895 L 66.33766,9.1021499 C 64.651951,9.5517047 63.049493,10.204637 61.558109,11.033725 L 56.112383,8.2889128 c -1.970928,1.4609237 -3.730521,3.1910632 -5.22513,5.1351362 l 2.648234,5.494014 c -0.855644,1.477262 -1.537042,3.067161 -2.016082,4.743334 l -5.791433,1.911821 c -0.188001,1.269731 -0.286444,2.568579 -0.286444,3.890587 0,1.164355 0.07633,2.310701 0.222789,3.435131 l 5.756315,2.009497 c 0.449555,1.685708 1.102486,3.288168 1.931575,4.779551 l -2.744813,5.445725 c 1.460924,1.970927 3.191063,3.730521 5.135137,5.22513 l 5.494014,-2.648233 c 1.477261,0.85564 3.067161,1.537039 4.743334,2.016081 L 67.8917,55.51812 c 1.26973,0.188002 2.568578,0.286444 3.890587,0.286444 1.16565,0 2.313889,-0.07601 3.43952,-0.222789 l 2.008399,-5.756314 c 1.684332,-0.449523 3.285984,-1.103103 4.776259,-1.931575 l 5.445725,2.744812 c 1.970928,-1.460924 3.730521,-3.191061 5.22513,-5.135136 l -2.648233,-5.494015 c 0.85564,-1.477262 1.537039,-3.067161 2.016082,-4.743334 l 5.79253,-1.91182 c 0.187995,-1.269731 0.285346,-2.56858 0.285346,-3.890588 0,-1.16565 -0.07601,-2.313889 -0.222789,-3.439521 L 92.143942,24.015886 C 91.694419,22.331554 91.04084,20.729903 90.212367,19.239628 l 2.744812,-5.445726 C 91.496255,11.822973 89.766118,10.063381 87.822043,8.5687715 L 82.328028,11.217006 C 80.850766,10.361361 79.260867,9.6799641 77.584694,9.2009234 L 75.672874,3.4094907 C 74.403143,3.2214898 73.104295,3.1230469 71.782287,3.1230469 Z m 0,15.0520191 a 11.288679,11.288679 0 0 1 11.288739,11.288739 11.288679,11.288679 0 0 1 -11.288739,11.28874 11.288679,11.288679 0 0 1 -11.28874,-11.28874 11.288679,11.288679 0 0 1 11.28874,-11.288739 z" />
-      <path d="m 38.326115,25.84777 c -1.583642,0 -3.142788,0.103807 -4.672127,0.303016 l -2.73312,7.829173 c -2.292736,0.611441 -4.472242,1.499494 -6.500676,2.627139 L 17.01345,32.873874 c -2.680664,1.987004 -5.073889,4.340169 -7.1067095,6.984309 l 3.6018685,7.472418 c -1.163764,2.009226 -2.090533,4.171652 -2.742078,6.451418 l -7.8769382,2.60027 C 2.6338924,58.109252 2.5,59.875819 2.5,61.673885 c 0,1.583642 0.1038125,3.142788 0.3030165,4.672128 l 7.8291725,2.73312 c 0.611441,2.292734 1.499494,4.472243 2.627139,6.500673 L 9.5261037,82.98655 c 1.9870063,2.680661 4.3401703,5.07389 6.9843093,7.106709 l 7.472419,-3.601867 c 2.009226,1.16376 4.171651,2.090533 6.451418,2.742079 l 2.60027,7.876932 C 34.761483,97.366114 36.528049,97.5 38.326115,97.5 c 1.585404,0 3.147126,-0.103373 4.678099,-0.303015 l 2.731628,-7.829178 c 2.290862,-0.611397 4.469272,-1.500329 6.496197,-2.627132 l 7.406741,3.733224 c 2.680664,-1.987007 5.07389,-4.340171 7.10671,-6.984313 l -3.601866,-7.472415 c 1.163756,-2.00923 2.090529,-4.171655 2.742076,-6.45142 l 7.878431,-2.60027 c 0.255691,-1.726964 0.3881,-3.49353 0.3881,-5.291596 0,-1.585404 -0.103373,-3.147127 -0.303016,-4.678099 L 66.020041,54.264159 C 65.408645,51.973296 64.51971,49.794888 63.392903,47.767962 l 3.733224,-7.406742 c -1.987006,-2.680664 -4.340168,-5.073889 -6.984309,-7.10671 l -7.472419,3.601867 c -2.009228,-1.163762 -4.171651,-2.090533 -6.451418,-2.742076 l -2.60027,-7.876939 C 41.890748,25.981661 40.124181,25.84777 38.326115,25.84777 Z m 0,20.472278 A 15.353754,15.353754 0 0 1 53.679952,61.673885 15.353754,15.353754 0 0 1 38.326115,77.027724 15.353754,15.353754 0 0 1 22.972279,61.673885 15.353754,15.353754 0 0 1 38.326115,46.320048 Z" />
-    </svg>
-  );
-};
-
-export default CogIcon;
diff --git a/src/components/Icons/Contact/Contact.module.scss b/src/components/Icons/Contact/Contact.module.scss
deleted file mode 100644
index 963c1dc..0000000
--- a/src/components/Icons/Contact/Contact.module.scss
+++ /dev/null
@@ -1,29 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.icon {
-  display: block;
-  margin: auto;
-  width: var(--icon-size, #{fun.convert-px(40)});
-}
-
-.envelop {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-}
-
-.lines {
-  fill: var(--color-fg);
-}
-
-.background {
-  fill: var(--color-shadow-dark);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-}
-
-.paper {
-  fill: var(--color-bg);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-}
diff --git a/src/components/Icons/Contact/Contact.tsx b/src/components/Icons/Contact/Contact.tsx
deleted file mode 100644
index 19295d0..0000000
--- a/src/components/Icons/Contact/Contact.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import styles from './Contact.module.scss';
-
-const ContactIcon = () => {
-  return (
-    <svg
-      viewBox="0 0 100 100"
-      xmlns="http://www.w3.org/2000/svg"
-      className={styles.icon}
-    >
-      <path
-        className={styles.background}
-        d="M 1.5262527,42.535416 H 98.473747 V 98.371662 H 1.5262527 Z"
-      />
-      <path
-        className={styles.envelop}
-        d="m 49.999985,1.6283075 c 2.855148,0 48.473753,40.8563885 48.473753,40.8563885 H 1.5262359 c 0,0 45.6186001,-40.8563885 48.4737491,-40.8563885 z"
-      />
-      <path
-        className={styles.paper}
-        d="M 8.3434839,28.463842 H 91.656465 V 97.348661 H 8.3434839 Z"
-      />
-      <path
-        className={styles.envelop}
-        d="M 49.999985,63.571925 98.473738,98.371692 H 1.5262359 Z"
-      />
-      <path
-        className={styles.lines}
-        d="m 24.562439,37.640923 h 50.875053 v 1.5 H 24.562439 Z"
-      />
-      <path
-        className={styles.lines}
-        d="m 24.562439,45.140923 h 50.875053 v 1.5 H 24.562439 Z"
-      />
-      <path
-        className={styles.lines}
-        d="m 24.562443,52.640923 h 50.875053 v 1.5 H 24.562443 Z"
-      />
-      <path
-        className={styles.lines}
-        d="M 24.562447,60.140923 H 75.4375 v 1.5 H 24.562447 Z"
-      />
-      <path
-        className={styles.envelop}
-        d="M 39.93749,70.965004 1.5262559,43.55838 v 54.813242 z"
-      />
-      <path
-        className={styles.envelop}
-        d="M 60.0625,70.965004 98.473738,43.55838 v 54.813242 z"
-      />
-    </svg>
-  );
-};
-
-export default ContactIcon;
diff --git a/src/components/Icons/Copyright/Copyright.module.scss b/src/components/Icons/Copyright/Copyright.module.scss
deleted file mode 100644
index 8ea801e..0000000
--- a/src/components/Icons/Copyright/Copyright.module.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.icon {
-  display: block;
-  width: var(--icon-size, #{fun.convert-px(40)});
-  fill: var(--color-fg);
-}
diff --git a/src/components/Icons/Copyright/Copyright.tsx b/src/components/Icons/Copyright/Copyright.tsx
deleted file mode 100644
index d27c042..0000000
--- a/src/components/Icons/Copyright/Copyright.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import styles from './Copyright.module.scss';
-
-const CopyrightIcon = () => {
-  return (
-    <svg
-      className={styles.icon}
-      viewBox="0 0 211.99811 63.999996"
-      xmlns="http://www.w3.org/2000/svg"
-    >
-      <title>CC BY SA</title>
-      <path d="m 175.53911,15.829498 c 0,-3.008 1.485,-4.514 4.458,-4.514 2.973,0 4.457,1.504 4.457,4.514 0,2.971 -1.486,4.457 -4.457,4.457 -2.971,0 -4.458,-1.486 -4.458,-4.457 z" />
-      <path d="m 188.62611,24.057498 v 13.085 h -3.656 v 15.542 h -9.944 v -15.541 h -3.656 v -13.086 c 0,-0.572 0.2,-1.057 0.599,-1.457 0.401,-0.399 0.887,-0.6 1.457,-0.6 h 13.144 c 0.533,0 1.01,0.2 1.428,0.6 0.417,0.4 0.628,0.886 0.628,1.457 z" />
-      <path d="m 179.94147,-1.9073486e-6 c -8.839,0 -16.34167,3.0848125073486 -22.51367,9.2578125073486 -6.285,6.4000004 -9.42969,13.9811874 -9.42969,22.7421874 0,8.762 3.14469,16.284312 9.42969,22.570312 6.361,6.286 13.86467,9.429688 22.51367,9.429688 8.799,0 16.43611,-3.181922 22.91211,-9.544922 6.096,-5.98 9.14453,-13.464078 9.14453,-22.455078 0,-8.952 -3.10646,-16.532188 -9.31446,-22.7421874 -6.172,-6.172 -13.75418,-9.2578125073486 -22.74218,-9.2578125073486 z M 180.05475,5.7714825 c 7.238,0 13.40967,2.55225 18.51367,7.6562495 5.103,5.106 7.65625,11.294313 7.65625,18.570313 0,7.391 -2.51397,13.50575 -7.54297,18.34375 -5.295,5.221 -11.50591,7.828125 -18.6289,7.828125 -7.162,0 -13.33268,-2.589484 -18.51368,-7.771484 -5.18,-5.178001 -7.76953,-11.310485 -7.76953,-18.396485 0,-7.047 2.60813,-13.238266 7.82813,-18.572265 5.029,-5.1040004 11.18103,-7.6582035 18.45703,-7.6582035 z" />
-      <path d="m 91.998554,27.114498 c 0.609,-3.924 2.189,-6.962 4.742,-9.114 2.552,-2.152 5.655996,-3.228 9.313996,-3.228 5.027,0 9.029,1.62 12,4.856 2.971,3.238 4.457,7.391 4.457,12.457 0,4.915 -1.543,9 -4.627,12.256 -3.088,3.256 -7.086,4.886 -12.002,4.886 -3.619,0 -6.742996,-1.085 -9.370996,-3.257 -2.629,-2.172 -4.209,-5.257 -4.743,-9.257 h 8.059 c 0.189996,3.886 2.532996,5.829 7.028996,5.829 2.246,0 4.057,-0.972 5.428,-2.914 1.373,-1.942 2.059,-4.534 2.059,-7.771 0,-3.391 -0.629,-5.971 -1.885,-7.743 -1.258,-1.771 -3.066,-2.657 -5.43,-2.657 -4.268,0 -6.667,1.885 -7.199996,5.656 h 2.342996 l -6.341996,6.343 -6.343,-6.343 z" />
-      <path d="m 105.94241,-1.8610229e-6 c -8.799996,0 -16.304676,3.1054062610229 -22.513666,9.3164061610229 -6.285,6.3999997 -9.42969,13.9625467 -9.42969,22.6855467 0,8.763 3.14469,16.28336 9.42969,22.568359 6.361,6.286001 13.86467,9.429688 22.513666,9.429688 8.836,0 16.47511,-3.162328 22.91211,-9.486328 6.096,-6.057 9.14453,-13.559672 9.14453,-22.513672 0,-8.952 -3.10646,-16.513547 -9.31446,-22.6855468 -6.211,-6.21 -13.79118,-9.3144530610229 -22.74218,-9.3144530610229 z M 106.05569,5.7714825 c 7.275,0 13.44667,2.5698437 18.51367,7.7148435 5.103,5.028 7.65625,11.200672 7.65625,18.513672 0,7.353 -2.51397,13.46775 -7.54297,18.34375 -5.295,5.219 -11.50591,7.828125 -18.6289,7.828125 -7.161996,0 -13.332676,-2.589484 -18.513676,-7.771484 -5.18,-5.143 -7.76953,-11.275391 -7.76953,-18.400391 0,-7.046 2.60813,-13.217672 7.82813,-18.513672 5.029,-5.1429998 11.18103,-7.7148435 18.457026,-7.7148435 z" />
-      <path d="M 31.942383,5.9265138e-7 C 23.066111,5.9265138e-7 15.579851,3.1065496 9.484666,9.3147376 6.399571,12.400832 4.046856,15.896269 2.427808,19.801386 0.80876,23.706506 0,27.771846 0,32.000976 c 0,4.26713 0.800415,8.32413 2.400463,12.17225 1.600051,3.84811 3.933123,7.30532 7.000216,10.37141 3.067093,3.06609 6.534587,5.40951 10.400708,7.02756 3.867116,1.62105 7.914819,2.4278 12.142946,2.4278 4.22813,0 8.32441,-0.8171 12.28553,-2.45515 3.96313,-1.63805 7.50614,-4.00301 10.62923,-7.0881 3.0081,-2.93309 5.28529,-6.31477 6.82834,-10.14289 1.54104,-3.82712 2.31257,-7.93174 2.31257,-12.31288 0,-4.34313 -0.78277,-8.44771 -2.34382,-12.31483 C 60.094133,15.82003 57.808593,12.380471 54.800503,9.3713796 48.515313,3.1241896 40.893653,5.9265136e-7 31.942383,5.9265138e-7 Z M 32.057623,5.7716626 c 7.23822,0 13.42863,2.571923 18.57478,7.7150794 2.47408,2.478074 4.35948,5.297144 5.65252,8.459244 1.29504,3.16209 1.94342,6.51384 1.94342,10.05694 0,7.35423 -2.49445,13.46816 -7.4846,18.34432 -2.59208,2.51407 -5.49406,4.43661 -8.71316,5.77166 -3.2231,1.33404 -6.54486,1.9981 -9.97296,1.9981 -3.467107,0 -6.782568,-0.65672 -9.943661,-1.97076 -3.164098,-1.31604 -5.999858,-3.21894 -8.513933,-5.71502 -2.515077,-2.49507 -4.447918,-5.33279 -5.800959,-8.51588 -1.354042,-3.1791 -2.029358,-6.48331 -2.029358,-9.91242 0,-3.4671 0.675316,-6.79186 2.029358,-9.97295 1.352043,-3.1811 3.285882,-6.046798 5.800959,-8.599875 4.991151,-5.1041594 11.14337,-7.6584384 18.457594,-7.6584384 z" />
-      <path d="m 50.114533,26.687816 -4.22913,2.22907 c -0.45702,-0.95103 -1.02003,-1.61905 -1.68605,-2.00006 -0.66802,-0.38001 -1.30704,-0.57102 -1.91406,-0.57102 -2.85709,0 -4.28713,1.88506 -4.28713,5.65717 0,1.71406 0.363,3.0841 1.08603,4.11313 0.72302,1.02903 1.78906,1.54405 3.2011,1.54405 1.86506,0 3.1801,-0.91503 3.94112,-2.74309 l 4.00012,2.00007 c -0.87502,1.56304 -2.05706,2.79108 -3.54111,3.68611 -1.48604,0.89602 -3.10509,1.34304 -4.85715,1.34304 -2.89608,0 -5.20915,-0.87503 -6.94121,-2.62908 -1.73605,-1.75205 -2.60207,-4.19013 -2.60207,-7.31323 0,-3.04809 0.88502,-5.46616 2.65808,-7.25722 1.77005,-1.79005 4.00812,-2.68608 6.7132,-2.68608 3.96212,-0.002 6.78321,1.54105 8.45826,4.62714 z" />
-      <path d="m 31.656963,26.687816 -4.287128,2.22907 c -0.458013,-0.95103 -1.019029,-1.61905 -1.685048,-2.00006 -0.667024,-0.38001 -1.286042,-0.57102 -1.858057,-0.57102 -2.856087,0 -4.28613,1.88506 -4.28613,5.65717 0,1.71406 0.362014,3.0841 1.085029,4.11313 0.724025,1.02903 1.791056,1.54405 3.201101,1.54405 1.867057,0 3.181095,-0.91503 3.944118,-2.74309 l 3.942125,2.00007 c -0.83803,1.56304 -2.000065,2.79108 -3.486111,3.68611 -1.484043,0.89602 -3.123093,1.34304 -4.914149,1.34304 -2.857088,0 -5.163158,-0.87503 -6.915212,-2.62908 -1.752053,-1.75205 -2.62808,-4.19013 -2.62808,-7.31323 0,-3.04809 0.886028,-5.46616 2.657081,-7.25722 1.771054,-1.79005 4.009125,-2.68608 6.715205,-2.68608 3.963122,-0.002 6.800209,1.54105 8.515256,4.62714 z" />
-    </svg>
-  );
-};
-
-export default CopyrightIcon;
diff --git a/src/components/Icons/Hamburger/Hamburger.module.scss b/src/components/Icons/Hamburger/Hamburger.module.scss
deleted file mode 100644
index 9965c5e..0000000
--- a/src/components/Icons/Hamburger/Hamburger.module.scss
+++ /dev/null
@@ -1,56 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.icon {
-  position: relative;
-  width: 100%;
-
-  &,
-  &::before,
-  &::after {
-    background: var(--color-primary-lighter);
-    background-image: linear-gradient(
-      to right,
-      var(--color-primary-light) 0%,
-      var(--color-primary-lighter) 100%
-    );
-    border: fun.convert-px(1) solid var(--color-primary-darker);
-    border-radius: fun.convert-px(3);
-    display: block;
-    height: fun.convert-px(7);
-    margin: auto;
-    transition: all 0.25s ease-in-out 0s, transform 0.4s ease-in 0s;
-  }
-
-  &::before,
-  &::after {
-    content: "";
-    position: absolute;
-    left: fun.convert-px(-1);
-    right: fun.convert-px(-1);
-  }
-
-  &::before {
-    bottom: fun.convert-px(15);
-  }
-
-  &::after {
-    top: fun.convert-px(15);
-  }
-
-  &--active {
-    background: transparent;
-    border: transparent;
-
-    &::before {
-      transform-origin: 50% 50%;
-      transform: rotate(45deg);
-      bottom: 0;
-    }
-
-    &::after {
-      transform-origin: 50% 50%;
-      transform: rotate(-45deg);
-      top: 0;
-    }
-  }
-}
diff --git a/src/components/Icons/Hamburger/Hamburger.tsx b/src/components/Icons/Hamburger/Hamburger.tsx
deleted file mode 100644
index 9b39272..0000000
--- a/src/components/Icons/Hamburger/Hamburger.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import styles from './Hamburger.module.scss';
-
-const HamburgerIcon = ({ isActive }: { isActive: boolean }) => {
-  const withModifier = isActive ? ` ${styles['icon--active']}` : '';
-  const iconClasses = `${styles.icon} ${withModifier}`;
-
-  return <span className={iconClasses}></span>;
-};
-
-export default HamburgerIcon;
diff --git a/src/components/Icons/Home/Home.module.scss b/src/components/Icons/Home/Home.module.scss
deleted file mode 100644
index f2e7f9e..0000000
--- a/src/components/Icons/Home/Home.module.scss
+++ /dev/null
@@ -1,42 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.icon {
-  display: block;
-  margin: auto;
-  width: var(--icon-size, #{fun.convert-px(40)});
-}
-
-.wall {
-  fill: var(--color-bg);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-}
-
-.indoor {
-  fill: var(--color-shadow-dark);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-}
-
-.door {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-}
-
-.roof {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-}
-
-.chimney {
-  fill: var(--color-bg);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-}
-
-.lines {
-  fill: var(--color-primary-darker);
-  stroke-width: 4;
-}
diff --git a/src/components/Icons/Home/Home.tsx b/src/components/Icons/Home/Home.tsx
deleted file mode 100644
index 11c0c8c..0000000
--- a/src/components/Icons/Home/Home.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import styles from './Home.module.scss';
-
-const HomeIcon = () => {
-  return (
-    <svg
-      viewBox="0 0 100 100"
-      xmlns="http://www.w3.org/2000/svg"
-      className={styles.icon}
-    >
-      <path
-        className={styles.wall}
-        d="M 9.2669392,15.413749 H 90.709833 V 97.751815 H 9.2669392 Z"
-      />
-      <path
-        className={styles.indoor}
-        d="m 39.190941,65.836418 h 21.594871 v 31.91539 H 39.190941 Z"
-      />
-      <path
-        className={styles.door}
-        d="m 39.190941,65.836418 h 21.594871 v 31.91539 H 39.190941 Z"
-      />
-      <path
-        className={styles.roof}
-        d="M 4.8219096,11.719266 H 94.720716 l 3.47304,33.365604 H 1.7830046 Z"
-      />
-      <path
-        className={styles.chimney}
-        d="M 70.41848,2.2481852 H 82.957212 V 22.636212 H 70.41848 Z"
-      />
-      <path
-        className={styles.lines}
-        d="M 3.9536645,19.342648 H 61.003053 v 3.293563 H 3.9536645 Z"
-      />
-      <path
-        className={styles.lines}
-        d="m 38.973709,32.057171 h 57.049389 v 3.293563 H 38.973709 Z"
-      />
-    </svg>
-  );
-};
-
-export default HomeIcon;
diff --git a/src/components/Icons/Moon/Moon.module.scss b/src/components/Icons/Moon/Moon.module.scss
deleted file mode 100644
index 799a282..0000000
--- a/src/components/Icons/Moon/Moon.module.scss
+++ /dev/null
@@ -1,8 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.moon {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-  width: var(--icon-size, #{fun.convert-px(25)});
-}
diff --git a/src/components/Icons/Moon/Moon.tsx b/src/components/Icons/Moon/Moon.tsx
deleted file mode 100644
index 26f56a1..0000000
--- a/src/components/Icons/Moon/Moon.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { useIntl } from 'react-intl';
-import styles from './Moon.module.scss';
-
-const MoonIcon = () => {
-  const intl = useIntl();
-
-  return (
-    <svg
-      className={styles.moon}
-      viewBox="0 0 100 100"
-      xmlns="http://www.w3.org/2000/svg"
-    >
-      <title>
-        {intl.formatMessage({
-          defaultMessage: 'Dark theme',
-          description: 'Icons: Moon icon (dark theme)',
-          id: 'ode0YK',
-        })}
-      </title>
-      <path d="M 51.077315,1.9893942 A 43.319985,43.319985 0 0 1 72.840039,39.563145 43.319985,43.319985 0 0 1 29.520053,82.88313 43.319985,43.319985 0 0 1 5.4309911,75.569042 48.132997,48.132997 0 0 0 46.126047,98 48.132997,48.132997 0 0 0 94.260004,49.867002 48.132997,48.132997 0 0 0 51.077315,1.9893942 Z" />
-    </svg>
-  );
-};
-
-export default MoonIcon;
diff --git a/src/components/Icons/Projects/Projects.module.scss b/src/components/Icons/Projects/Projects.module.scss
deleted file mode 100644
index 3cf939a..0000000
--- a/src/components/Icons/Projects/Projects.module.scss
+++ /dev/null
@@ -1,40 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.icon {
-  display: block;
-  margin: auto;
-  width: var(--icon-size, #{fun.convert-px(40)});
-}
-
-.root,
-.separator,
-.cursor,
-.line,
-.text {
-  fill: var(--color-fg);
-}
-
-.stand {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-dark);
-
-  &--top {
-    stroke-width: 3;
-  }
-
-  &--bottom {
-    stroke-width: 2;
-  }
-}
-
-.screen {
-  fill: var(--color-bg);
-  stroke: var(--color-primary-dark);
-  stroke-width: 3;
-}
-
-.contour {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-dark);
-  stroke-width: 3;
-}
diff --git a/src/components/Icons/Projects/Projects.tsx b/src/components/Icons/Projects/Projects.tsx
deleted file mode 100644
index d4af247..0000000
--- a/src/components/Icons/Projects/Projects.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-import styles from './Projects.module.scss';
-
-const ProjectsIcon = () => {
-  return (
-    <svg
-      viewBox="0 0 100 100"
-      xmlns="http://www.w3.org/2000/svg"
-      className={styles.icon}
-    >
-      <path
-        d="M 1.0206528,11.991149 H 98.979347 V 78.466748 H 1.0206528 Z"
-        className={styles.contour}
-      />
-      <path
-        d="M 6.2503581,18.032451 H 93.563283 V 71.12731 H 6.2503581 Z"
-        className={styles.screen}
-      />
-      <path
-        d="m 40.038268,78.939276 c 4.614714,2.7794 4.333151,10.099225 0,17.60572 H 50 59.961731 c -4.333151,-7.506495 -4.614715,-14.82632 0,-17.60572 H 50 Z"
-        className={`${styles.stand} ${styles['stand--top']}`}
-      />
-      <path
-        d="m 31.084262,96.254656 h 37.831475 c 1.394769,0 2.517635,0.404907 2.517635,0.907864 v 1.179616 c 0,0.502956 -1.122866,0.907864 -2.517635,0.907864 H 31.084262 c -1.394769,0 -2.517635,-0.404908 -2.517635,-0.907864 V 97.16252 c 0,-0.502957 1.122866,-0.907864 2.517635,-0.907864 z"
-        className={`${styles.stand} ${styles['stand--bottom']}`}
-      />
-      <path
-        d="m 13.259277,26.737199 h 29.132596 v 2.567314 H 13.259277 Z"
-        className={styles.line}
-      />
-      <path
-        d="M 13.259277,36.439141 H 36.46805 v 2.567315 H 13.259277 Z"
-        className={styles.line}
-      />
-      <path
-        d="m 13.259277,46.141084 h 26.586812 v 2.567314 H 13.259277 Z"
-        className={styles.line}
-      />
-      <path
-        d="m 18.443194,65.930804 h 4.417548 v 1 h -4.417548 z"
-        className={styles.cursor}
-      />
-      <path
-        d="m 77.586096,42.217577 v -1.680914 l 6.160884,-2.39919 -6.160884,-2.406595 v -1.68832 l 7.604842,2.89532 v 2.38438 z"
-        className={styles.text}
-      />
-      <path
-        d="m 68.396606,43.291289 6.07943,-11.136982 h 1.688318 l -6.049809,11.136982 z"
-        className={styles.text}
-      />
-      <path
-        d="m 59.384832,39.322258 v -2.38438 l 7.604841,-2.89532 v 1.68832 l -6.168289,2.406595 6.168289,2.399191 v 1.680915 z"
-        className={styles.text}
-      />
-      <path
-        d="M 7.1079167,57.876372 H 92.892083 v 0.813634 H 7.1079167 Z"
-        className={styles.separator}
-      />
-      <path
-        d="m 17.042456,64.960616 q 0,0.632276 -0.426175,0.9816 -0.422681,0.345831 -1.254074,0.37727 v 0.611318 h -0.380763 v -0.600838 q -0.751047,-0.02795 -1.170236,-0.352818 -0.419189,-0.328364 -0.551931,-1.002559 l 0.89427,-0.164183 q 0.06637,0.394736 0.261992,0.579878 0.199115,0.181648 0.565905,0.216581 v -1.365857 q -0.01048,-0.007 -0.0524,-0.01398 -0.04192,-0.01048 -0.05589,-0.01048 -0.562412,-0.129244 -0.848857,-0.303907 -0.286445,-0.178155 -0.443642,-0.447135 -0.153701,-0.272472 -0.153701,-0.663715 0,-0.579878 0.394736,-0.894269 0.394736,-0.317886 1.159755,-0.349325 v -0.468093 h 0.380763 v 0.468095 q 0.681183,0.02445 1.047973,0.303911 0.36679,0.275967 0.527479,0.918723 l -0.92222,0.136236 q -0.104797,-0.600837 -0.653236,-0.674195 v 1.22962 l 0.03843,0.007 q 0.101305,0 0.614811,0.167676 0.517,0.167676 0.772007,0.496041 0.255006,0.324871 0.255006,0.817418 z m -2.061012,-2.731715 q -0.639264,0.04891 -0.639264,0.558918 0,0.157196 0.0524,0.2585 0.0524,0.09781 0.157197,0.167676 0.104797,0.06986 0.429668,0.174662 z m 1.152769,2.745688 q 0,-0.174662 -0.06288,-0.282954 -0.06288,-0.111783 -0.185141,-0.181648 -0.118771,-0.06986 -0.523987,-0.185142 v 1.28202 q 0.772006,-0.0524 0.772006,-0.632276 z"
-        className={styles.root}
-      />
-    </svg>
-  );
-};
-
-export default ProjectsIcon;
diff --git a/src/components/Icons/Search/Search.module.scss b/src/components/Icons/Search/Search.module.scss
deleted file mode 100644
index 4c42028..0000000
--- a/src/components/Icons/Search/Search.module.scss
+++ /dev/null
@@ -1,31 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.icon {
-  display: block;
-  margin: auto;
-  width: var(--icon-size, #{fun.convert-px(40)});
-}
-
-.big-handle {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-darker);
-  stroke-width: 3;
-}
-
-.glass {
-  fill: var(--color-bg-opacity);
-  stroke: var(--color-primary-darker);
-  stroke-width: 2;
-}
-
-.upright {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-darker);
-  stroke-width: 3;
-}
-
-.small-handle {
-  fill: var(--color-primary);
-  stroke: var(--color-primary-darker);
-  stroke-width: 2;
-}
diff --git a/src/components/Icons/Search/Search.tsx b/src/components/Icons/Search/Search.tsx
deleted file mode 100644
index abb7b53..0000000
--- a/src/components/Icons/Search/Search.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import styles from './Search.module.scss';
-
-const SearchIcon = () => {
-  return (
-    <svg
-      viewBox="0 0 100 100"
-      xmlns="http://www.w3.org/2000/svg"
-      className={styles.icon}
-    >
-      <path
-        className={styles['small-handle']}
-        d="m 45.39268,48.064692 5.611922,4.307881 -10.292886,13.414321 -5.611923,-4.307882 z"
-      />
-      <path
-        className={styles.upright}
-        d="M 90.904041,28.730105 A 27.725691,27.730085 0 0 1 63.17835,56.46019 27.725691,27.730085 0 0 1 35.45266,28.730105 27.725691,27.730085 0 0 1 63.17835,1.00002 27.725691,27.730085 0 0 1 90.904041,28.730105 Z"
-      />
-      <path
-        className={styles.glass}
-        d="M 82.438984,28.730105 A 19.260633,19.263685 0 0 1 63.17835,47.99379 19.260633,19.263685 0 0 1 43.917716,28.730105 19.260633,19.263685 0 0 1 63.17835,9.4664203 19.260633,19.263685 0 0 1 82.438984,28.730105 Z"
-      />
-      <path
-        className={styles['big-handle']}
-        d="m 35.826055,60.434903 5.75193,4.415356 c 0.998045,0.766128 1.184879,2.186554 0.418913,3.184809 L 18.914717,98.117182 c -0.765969,0.998256 -2.186094,1.185131 -3.18414,0.418997 L 9.9786472,94.120827 C 8.9806032,93.354698 8.7937692,91.934273 9.5597392,90.936014 L 32.641919,60.853903 c 0.765967,-0.998254 2.186091,-1.185129 3.184136,-0.419 z"
-      />
-    </svg>
-  );
-};
-
-export default SearchIcon;
diff --git a/src/components/Icons/Sun/Sun.module.scss b/src/components/Icons/Sun/Sun.module.scss
deleted file mode 100644
index 5682aa3..0000000
--- a/src/components/Icons/Sun/Sun.module.scss
+++ /dev/null
@@ -1,8 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.sun {
-  fill: var(--color-primary-lighter);
-  stroke: var(--color-primary-darker);
-  stroke-width: 4;
-  width: var(--icon-size, #{fun.convert-px(25)});
-}
diff --git a/src/components/Icons/Sun/Sun.tsx b/src/components/Icons/Sun/Sun.tsx
deleted file mode 100644
index 12f47d3..0000000
--- a/src/components/Icons/Sun/Sun.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { useIntl } from 'react-intl';
-import styles from './Sun.module.scss';
-
-const SunIcon = () => {
-  const intl = useIntl();
-
-  return (
-    <svg
-      className={styles.sun}
-      viewBox="0 0 100 100"
-      xmlns="http://www.w3.org/2000/svg"
-    >
-      <title>
-        {intl.formatMessage({
-          defaultMessage: 'Light theme',
-          description: 'Icons: Sun icon (light theme)',
-          id: 'KeRtm/',
-        })}
-      </title>
-      <path d="M 69.398043,50.000437 A 19.399259,19.399204 0 0 1 49.998784,69.399641 19.399259,19.399204 0 0 1 30.599525,50.000437 19.399259,19.399204 0 0 1 49.998784,30.601234 19.399259,19.399204 0 0 1 69.398043,50.000437 Z m 27.699233,1.125154 c 2.657696,0.0679 1.156196,12.061455 -1.435545,11.463959 L 80.113224,59.000697 c -2.589801,-0.597494 -1.625657,-8.345536 1.032041,-8.278609 z m -18.06653,37.251321 c 1.644087,2.091234 -9.030355,8.610337 -10.126414,6.188346 L 62.331863,80.024585 c -1.096058,-2.423931 5.197062,-6.285342 6.839209,-4.194107 z M 38.611418,97.594444 C 38.02653,100.18909 26.24148,95.916413 27.436475,93.54001 l 7.168026,-14.256474 c 1.194024,-2.376403 8.102101,0.151313 7.517214,2.744986 z M 6.1661563,71.834242 C 3.7916868,73.028262 -0.25499873,61.16274 2.3386824,60.577853 L 17.905618,57.067567 c 2.593681,-0.584886 4.894434,6.403678 2.518995,7.598668 z M 6.146757,30.055146 c -2.3764094,-1.194991 4.46571,-11.714209 6.479353,-9.97798 l 12.090589,10.414462 c 2.014613,1.736229 -1.937017,7.926514 -4.314396,6.731524 z M 38.56777,4.2639045 C 37.982883,1.6682911 50.480855,0.41801247 50.415868,3.0766733 L 50.020123,19.028638 c -0.06596,2.657691 -7.357169,3.394862 -7.943027,0.800218 z m 40.403808,9.1622435 c 1.635357,-2.098023 10.437771,6.872168 8.339742,8.506552 l -12.58818,9.805327 c -2.099,1.634383 -7.192276,-3.626682 -5.557888,-5.724706 z M 97.096306,50.69105 c 2.657696,-0.06596 1.164926,12.462047 -1.425846,11.863582 L 80.122924,58.96578 c -2.590771,-0.597496 -1.636327,-7.814 1.021371,-7.879957 z" />
-    </svg>
-  );
-};
-
-export default SunIcon;
diff --git a/src/components/Icons/index.tsx b/src/components/Icons/index.tsx
deleted file mode 100644
index 5fe2c19..0000000
--- a/src/components/Icons/index.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import ArrowIcon from './Arrow/Arrow';
-import BlogIcon from './Blog/Blog';
-import CloseIcon from './Close/Close';
-import CogIcon from './Cog/Cog';
-import ContactIcon from './Contact/Contact';
-import CopyrightIcon from './Copyright/Copyright';
-import CVIcon from './CV/CV';
-import HamburgerIcon from './Hamburger/Hamburger';
-import HomeIcon from './Home/Home';
-import MoonIcon from './Moon/Moon';
-import ProjectsIcon from './Projects/Projects';
-import SearchIcon from './Search/Search';
-import SunIcon from './Sun/Sun';
-
-export {
-  ArrowIcon,
-  BlogIcon,
-  CloseIcon,
-  CogIcon,
-  ContactIcon,
-  CopyrightIcon,
-  CVIcon,
-  HamburgerIcon,
-  HomeIcon,
-  MoonIcon,
-  ProjectsIcon,
-  SearchIcon,
-  SunIcon,
-};
diff --git a/src/components/Layouts/Layout.module.scss b/src/components/Layouts/Layout.module.scss
deleted file mode 100644
index 33339d4..0000000
--- a/src/components/Layouts/Layout.module.scss
+++ /dev/null
@@ -1,20 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.noscript {
-  width: 100%;
-  padding: var(--spacing-xs) var(--spacing-sm);
-  position: fixed;
-  top: 0;
-  z-index: 10;
-  background: var(--color-bg);
-  border-bottom: fun.convert-px(3) solid var(--color-border);
-  color: var(--color-primary-darker);
-  font-size: var(--font-size-sm);
-  font-weight: 600;
-  text-align: center;
-}
-
-.noscript-spacing {
-  width: 100%;
-  height: fun.convert-px(80);
-}
diff --git a/src/components/Layouts/Layout.tsx b/src/components/Layouts/Layout.tsx
deleted file mode 100644
index ada32b3..0000000
--- a/src/components/Layouts/Layout.tsx
+++ /dev/null
@@ -1,155 +0,0 @@
-import Footer from '@components/Footer/Footer';
-import Header from '@components/Header/Header';
-import Main from '@components/Main/Main';
-import Breadcrumb from '@components/Breadcrumb/Breadcrumb';
-import { settings } from '@utils/config';
-import Head from 'next/head';
-import { useRouter } from 'next/router';
-import { ReactElement, ReactNode, useEffect, useRef } from 'react';
-import { useIntl } from 'react-intl';
-import { SearchAction, WebSite, WithContext } from 'schema-dts';
-import styles from './Layout.module.scss';
-import Script from 'next/script';
-
-const Layout = ({
-  children,
-  isHome = false,
-}: {
-  children: ReactNode;
-  isHome?: boolean;
-}) => {
-  const intl = useIntl();
-  const { asPath, locale } = useRouter();
-  const ref = useRef<HTMLSpanElement>(null);
-
-  useEffect(() => {
-    ref.current?.focus();
-  }, [asPath]);
-
-  type QueryAction = SearchAction & {
-    'query-input': string;
-  };
-
-  const searchActionSchema: QueryAction = {
-    '@type': 'SearchAction',
-    target: {
-      '@type': 'EntryPoint',
-      urlTemplate: `${settings.url}/recherche?s={search_term_string}`,
-    },
-    query: 'required',
-    'query-input': 'required name=search_term_string',
-  };
-
-  const schemaJsonLd: WithContext<WebSite> = {
-    '@context': 'https://schema.org',
-    '@id': `${settings.url}`,
-    '@type': 'WebSite',
-    name: settings.name,
-    description: locale?.startsWith('en')
-      ? settings.baseline.en
-      : settings.baseline.fr,
-    url: settings.url,
-    author: { '@id': `${settings.url}/#branding` },
-    copyrightYear: Number(settings.copyright.startYear),
-    creator: { '@id': `${settings.url}/#branding` },
-    editor: { '@id': `${settings.url}/#branding` },
-    inLanguage: settings.locales.defaultLocale,
-    potentialAction: searchActionSchema,
-  };
-
-  return (
-    <>
-      <Head>
-        <meta property="og:site_name" content={settings.name} />
-        <meta
-          property="og:locale"
-          content={`${settings.locales.defaultLocale}_${settings.locales.defaultCountry}`}
-        />
-        <meta property="twitter:card" content="summary" />
-        <meta property="twitter:site" content={settings.twitterId} />
-        <meta property="twitter:creator" content={settings.twitterId} />
-        <meta
-          name="theme-color"
-          content="#14578a"
-          media="(prefers-color-scheme: light)"
-        />
-        <meta
-          name="theme-color"
-          content="#85bbd6"
-          media="(prefers-color-scheme: dark)"
-        />
-        <link
-          rel="alternate"
-          href="/feed.xml"
-          type="application/rss+xml"
-          title={`${settings.name}'s RSS feed`}
-        />
-        <link
-          rel="alternate"
-          href="/atom.xml"
-          type="application/atom+xml"
-          title={`${settings.name}'s Atom feed`}
-        />
-        <link
-          rel="alternate"
-          href="/feed.json"
-          type="application/feed+json"
-          title={`${settings.name}'s Json feed`}
-        />
-        <link rel="icon" href="/favicon.ico" sizes="any" />
-        <link rel="icon" href="/icon.svg" type="image/svg+xml" />
-        <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
-        <link rel="manifest" href="/manifest.webmanifest" />
-      </Head>
-      <Script
-        id="schema-layout"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      ></Script>
-      <Script
-        strategy="afterInteractive"
-        async
-        src={`${settings.ackee.url}/${settings.ackee.filename}`}
-        data-ackee-server={settings.ackee.url}
-        data-ackee-domain-id={settings.ackee.siteId}
-      />
-      <noscript>
-        <div className={styles['noscript-spacing']}></div>
-      </noscript>
-      <span ref={ref} tabIndex={-1} />
-      <a href="#main" className="screen-reader-text">
-        {intl.formatMessage({
-          defaultMessage: 'Skip to content',
-          description: 'Layout: Skip to content button',
-          id: 'iqAbyn',
-        })}
-      </a>
-      <Header isHome={isHome} />
-      <Main>{children}</Main>
-      <Footer />
-      <noscript>
-        <div className={styles.noscript}>
-          {intl.formatMessage({
-            defaultMessage:
-              'Without Javascript, some features may not work like loading more posts or use search. If you want to benefit from these features, please activate Javascript.',
-            description: 'Layout: noscript banner',
-            id: 'LR70nt',
-          })}
-        </div>
-      </noscript>
-    </>
-  );
-};
-
-export const getLayout = (page: ReactElement) => {
-  const pageTitle: string = page.props.breadcrumbTitle;
-
-  return (
-    <Layout>
-      <Breadcrumb pageTitle={pageTitle} />
-      {page}
-    </Layout>
-  );
-};
-
-export default Layout;
diff --git a/src/components/MDX/CodeBlock/CodeBlock.tsx b/src/components/MDX/CodeBlock/CodeBlock.tsx
deleted file mode 100644
index c330063..0000000
--- a/src/components/MDX/CodeBlock/CodeBlock.tsx
+++ /dev/null
@@ -1,115 +0,0 @@
-import {
-  PrismDefaultPlugins,
-  PrismLanguages,
-  PrismPlugins,
-} from '@ts/types/prism';
-import { usePrismTheme } from '@utils/providers/prism-theme';
-import { useRouter } from 'next/router';
-import Prism from 'prismjs';
-import { useCallback, useEffect, useMemo } from 'react';
-import { useIntl } from 'react-intl';
-
-const CodeBlock = ({
-  code,
-  language,
-  plugins,
-}: {
-  code: string;
-  language: PrismLanguages;
-  plugins: PrismPlugins[];
-}) => {
-  const intl = useIntl();
-  const router = useRouter();
-  const { setCodeBlocks } = usePrismTheme();
-
-  useEffect(() => {
-    const allPre: NodeListOf<HTMLPreElement> = document.querySelectorAll(
-      'pre[data-prismjs-color-scheme-current]'
-    );
-    setCodeBlocks(allPre);
-  }, [setCodeBlocks, router.asPath]);
-
-  const defaultPlugins: PrismDefaultPlugins[] = useMemo(
-    () => [
-      'autoloader',
-      'toolbar',
-      'show-language',
-      'copy-to-clipboard',
-      'color-scheme',
-      'match-braces',
-      'normalize-whitespace',
-    ],
-    []
-  );
-
-  const loadPrismPlugins = useCallback(
-    async (prismPlugins: (PrismDefaultPlugins | PrismPlugins)[]) => {
-      for (const plugin of prismPlugins) {
-        try {
-          if (plugin === 'color-scheme') {
-            await import(`@utils/plugins/prism-${plugin}`);
-          } else {
-            await import(`prismjs/plugins/${plugin}/prism-${plugin}.min.js`);
-
-            if (plugin === 'autoloader')
-              Prism.plugins.autoloader.languages_path = '/prism/';
-          }
-        } catch (error) {
-          console.error('CodeBlock: an error occurred with Prism.');
-          console.error(error);
-        }
-      }
-    },
-    []
-  );
-
-  useEffect(() => {
-    loadPrismPlugins([...defaultPlugins, ...plugins]).then(() => {
-      Prism.highlightAll();
-    });
-  }, [loadPrismPlugins, defaultPlugins, plugins]);
-
-  const copyText = intl.formatMessage({
-    defaultMessage: 'Copy',
-    description: 'Prism: copy button text (no clicked)',
-    id: '/ly3AC',
-  });
-  const copiedText = intl.formatMessage({
-    defaultMessage: 'Copied!',
-    description: 'Prism: copy button text (clicked)',
-    id: 'OV9r1K',
-  });
-  const errorText = intl.formatMessage({
-    defaultMessage: 'Use Ctrl+c to copy',
-    description: 'Prism: error text',
-    id: 'z9qkcQ',
-  });
-  const darkTheme = intl.formatMessage({
-    defaultMessage: 'Dark Theme 🌙',
-    description: 'Prism: toggle dark theme button text',
-    id: 'nFMdWI',
-  });
-  const lightTheme = intl.formatMessage({
-    defaultMessage: 'Light Theme 🌞',
-    description: 'Prism: toggle light theme button text',
-    id: 'Ua2g2p',
-  });
-
-  const defaultPluginsClasses = 'match-braces';
-  const pluginsClasses = plugins.join(' ');
-
-  return (
-    <pre
-      className={`language-${language} ${defaultPluginsClasses} ${pluginsClasses}`}
-      data-prismjs-copy={copyText}
-      data-prismjs-copy-success={copiedText}
-      data-prismjs-copy-error={errorText}
-      data-prismjs-color-scheme-dark={darkTheme}
-      data-prismjs-color-scheme-light={lightTheme}
-    >
-      <code className={`language-${language}`}>{code}</code>
-    </pre>
-  );
-};
-
-export default CodeBlock;
diff --git a/src/components/MDX/Gallery/Gallery.module.scss b/src/components/MDX/Gallery/Gallery.module.scss
deleted file mode 100644
index 2654b59..0000000
--- a/src/components/MDX/Gallery/Gallery.module.scss
+++ /dev/null
@@ -1,32 +0,0 @@
-@use "@styles/abstracts/mixins" as mix;
-@use "@styles/abstracts/placeholders";
-
-.wrapper {
-  @extend %reset-list;
-
-  display: grid;
-  grid-template-columns: minmax(0, 1fr);
-  gap: var(--spacing-sm);
-  max-width: 100%;
-  margin: var(--spacing-sm) 0;
-
-  @for $i from 0 to 6 {
-    &--#{$i}-columns {
-      @include mix.media("screen") {
-        @include mix.dimensions("xs") {
-          grid-template-columns: repeat(2, minmax(0, 1fr));
-        }
-
-        @include mix.dimensions("sm") {
-          grid-template-columns: repeat(#{$i}, minmax(0, 1fr));
-        }
-      }
-    }
-  }
-}
-
-.item {
-  > figure {
-    margin: 0;
-  }
-}
diff --git a/src/components/MDX/Gallery/Gallery.tsx b/src/components/MDX/Gallery/Gallery.tsx
deleted file mode 100644
index 561ec53..0000000
--- a/src/components/MDX/Gallery/Gallery.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { Children, ReactElement } from 'react';
-import styles from './Gallery.module.scss';
-
-const Gallery = ({
-  children,
-  columns = 2,
-}: {
-  children: ReactElement;
-  columns: number;
-}) => {
-  const columnClass = styles[`wrapper--${columns}-columns`];
-
-  return (
-    <ul className={`${styles.wrapper} ${columnClass}`}>
-      {Children.map(children, (child) => {
-        return <li className={styles.item}>{child}</li>;
-      })}
-    </ul>
-  );
-};
-
-export default Gallery;
diff --git a/src/components/MDX/Link/Link.tsx b/src/components/MDX/Link/Link.tsx
deleted file mode 100644
index 40e773b..0000000
--- a/src/components/MDX/Link/Link.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import { ReactChildren } from 'react';
-
-const Link = ({
-  children,
-  target,
-  isExternal = false,
-  lang,
-}: {
-  children: ReactChildren;
-  target: string;
-  isExternal: boolean;
-  lang?: string;
-}) => {
-  const className = isExternal ? 'external' : '';
-
-  return (
-    <a href={target} className={className} hrefLang={lang}>
-      {children}
-    </a>
-  );
-};
-
-export default Link;
diff --git a/src/components/MDX/ResponsiveImage/ResponsiveImage.module.scss b/src/components/MDX/ResponsiveImage/ResponsiveImage.module.scss
deleted file mode 100644
index cf2b77f..0000000
--- a/src/components/MDX/ResponsiveImage/ResponsiveImage.module.scss
+++ /dev/null
@@ -1,50 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.wrapper {
-  width: 100%;
-  max-width: 100%;
-  margin: var(--spacing-sm) auto;
-  position: relative;
-  text-align: center;
-}
-
-.caption {
-  margin: 0;
-  padding: fun.convert-px(4) var(--spacing-2xs);
-  background: var(--color-bg-secondary);
-  border: fun.convert-px(1) solid var(--color-border);
-  box-shadow: 0 fun.convert-px(-1) fun.convert-px(1) fun.convert-px(1)
-    var(--color-shadow-light);
-  font-weight: 500;
-}
-
-.link {
-  display: flex;
-  flex-flow: column;
-  background: none;
-  text-decoration: none;
-
-  .caption {
-    color: var(--color-primary-darker);
-  }
-
-  &:hover,
-  &:focus {
-    transform: scale(1.1);
-  }
-
-  &:focus {
-    .caption {
-      text-decoration: underline solid var(--color-primary-darker)
-        fun.convert-px(3);
-    }
-  }
-
-  &:active {
-    transform: scale(0.9);
-
-    .caption {
-      text-decoration: none;
-    }
-  }
-}
diff --git a/src/components/MDX/ResponsiveImage/ResponsiveImage.tsx b/src/components/MDX/ResponsiveImage/ResponsiveImage.tsx
deleted file mode 100644
index 6c39e7f..0000000
--- a/src/components/MDX/ResponsiveImage/ResponsiveImage.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import { ResponsiveImageProps } from '@ts/types/app';
-import Image from 'next/image';
-import Link from 'next/link';
-import styles from './ResponsiveImage.module.scss';
-
-const ResponsiveImage = (props: ResponsiveImageProps) => {
-  const { caption, linkTarget, ...attributes } = props;
-
-  return (
-    <figure className={styles.wrapper}>
-      {linkTarget ? (
-        <Link href={linkTarget}>
-          <a className={styles.link}>
-            <Image
-              alt={attributes.alt}
-              layout={attributes.layout || 'intrinsic'}
-              {...attributes}
-            />
-            {caption && (
-              <figcaption className={styles.caption}>{caption}</figcaption>
-            )}
-          </a>
-        </Link>
-      ) : (
-        <>
-          <Image
-            alt={attributes.alt}
-            layout={attributes.layout || 'intrinsic'}
-            {...attributes}
-          />
-          {caption && (
-            <figcaption className={styles.caption}>{caption}</figcaption>
-          )}
-        </>
-      )}
-    </figure>
-  );
-};
-
-export default ResponsiveImage;
diff --git a/src/components/MDX/index.tsx b/src/components/MDX/index.tsx
deleted file mode 100644
index bc7aa35..0000000
--- a/src/components/MDX/index.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import CodeBlock from './CodeBlock/CodeBlock';
-import Gallery from './Gallery/Gallery';
-import Link from './Link/Link';
-import ResponsiveImage from './ResponsiveImage/ResponsiveImage';
-
-export { CodeBlock, Gallery, Link, ResponsiveImage };
diff --git a/src/components/Main/Main.module.scss b/src/components/Main/Main.module.scss
deleted file mode 100644
index 819474c..0000000
--- a/src/components/Main/Main.module.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-.wrapper {
-  flex: 1;
-
-  :global {
-    animation: fade-in 1.5s ease-in-out 0s 1;
-  }
-}
diff --git a/src/components/Main/Main.tsx b/src/components/Main/Main.tsx
deleted file mode 100644
index b21ab1c..0000000
--- a/src/components/Main/Main.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { FunctionComponent } from 'react';
-import styles from './Main.module.scss';
-
-const Main: FunctionComponent = ({ children }) => {
-  return (
-    <main id="main" className={styles.wrapper}>
-      {children}
-    </main>
-  );
-};
-
-export default Main;
diff --git a/src/components/MainNav/MainNav.module.scss b/src/components/MainNav/MainNav.module.scss
deleted file mode 100644
index f3e6c10..0000000
--- a/src/components/MainNav/MainNav.module.scss
+++ /dev/null
@@ -1,242 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-@use "@styles/abstracts/placeholders";
-
-.wrapper {
-  --icon-size: #{fun.convert-px(30)};
-
-  display: flex;
-  flex-flow: column nowrap;
-  align-items: center;
-  height: var(--btn-size);
-  width: calc(var(--btn-size) * 1.2);
-  background: var(--color-bg);
-  position: relative;
-
-  @include mix.media("screen") {
-    @include mix.dimensions("sm") {
-      background: inherit;
-    }
-
-    @include mix.dimensions("md") {
-      width: unset;
-      height: unset;
-    }
-  }
-}
-
-.label {
-  --draw-border-thickness: #{fun.convert-px(5)};
-  --draw-border-color1: var(--color-primary-light);
-  --draw-border-color2: var(--color-primary-lighter);
-
-  flex: 1;
-  display: flex;
-  flex-flow: column nowrap;
-  width: 100%;
-  padding: var(--spacing-2xs);
-
-  &:hover {
-    @extend %draw-borders;
-  }
-
-  @include mix.media("screen") {
-    @include mix.dimensions("md") {
-      display: none;
-    }
-  }
-}
-
-.checkbox {
-  position: absolute;
-
-  // centered checkbox = btn-size - approximated checkbox size / 2
-  top: calc((var(--btn-size) - #{fun.convert-px(14)}) / 2);
-  left: calc(((var(--btn-size) * 1.2) - #{fun.convert-px(14)}) / 2);
-  opacity: 0;
-  cursor: pointer;
-
-  &:hover {
-    ~ .label {
-      @extend %draw-borders;
-    }
-  }
-
-  &:focus {
-    ~ .label {
-      @extend %draw-borders;
-    }
-  }
-
-  @include mix.media("screen") {
-    @include mix.dimensions("md") {
-      display: none;
-    }
-  }
-}
-
-.nav {
-  display: flex;
-  flex-flow: column wrap;
-  place-content: center;
-  padding-bottom: var(--toolbar-size);
-  position: fixed;
-  bottom: 0;
-  z-index: -1;
-  background: var(--color-bg-opacity);
-  box-shadow: 0 0 fun.convert-px(3) 0 var(--color-shadow-dark);
-  text-align: center;
-  opacity: 1;
-  visibility: visible;
-  transform: translateY(0);
-  transition: all 0.8s ease-in-out 0s;
-
-  @include mix.media("screen") {
-    @include mix.dimensions("sm") {
-      padding-bottom: 0;
-      position: absolute;
-      bottom: auto;
-      left: auto;
-      right: auto;
-      top: calc(var(--btn-size) + var(--spacing-sm));
-      z-index: unset;
-      border-bottom-width: fun.convert-px(5);
-      transform-origin: 50% -100%;
-    }
-
-    @include mix.dimensions("md") {
-      background: transparent;
-      border: none;
-      box-shadow: none;
-      position: relative;
-      top: 0;
-    }
-  }
-}
-
-.list {
-  @extend %reset-list;
-
-  @include mix.media("screen") {
-    @include mix.dimensions(null, "2xs", "height") {
-      display: grid;
-      grid-template-columns: min-content min-content;
-      max-height: calc(100vh - var(--toolbar-size));
-    }
-
-    @include mix.dimensions("md") {
-      display: flex;
-      flex-flow: row wrap;
-      align-items: center;
-      gap: var(--spacing-2xs);
-    }
-  }
-}
-
-.link {
-  --draw-border-thickness: #{fun.convert-px(4)};
-  --draw-border-color1: var(--color-primary-light);
-  --draw-border-color2: var(--color-primary-lighter);
-
-  display: block;
-  min-width: fun.convert-px(85);
-  padding: var(--spacing-xs) var(--spacing-xs) var(--spacing-2xs);
-  background: var(--color-bg);
-  background-repeat: no-repeat;
-  font-size: var(--font-size-sm);
-  font-variant: small-caps;
-  font-weight: 600;
-  text-decoration: none;
-
-  @include mix.media("screen") {
-    @include mix.dimensions("md") {
-      margin: 0;
-      background-color: inherit;
-      border-radius: 8%;
-    }
-  }
-
-  &:hover,
-  &:focus {
-    @extend %draw-borders;
-  }
-
-  &:focus {
-    color: var(--color-primary-light);
-  }
-
-  &:active {
-    --draw-border-color1: var(--color-primary-dark);
-    --draw-border-color2: var(--color-primary-light);
-
-    @extend %draw-borders;
-  }
-
-  &.current {
-    background-image: linear-gradient(to right, transparent, transparent),
-      linear-gradient(to bottom, transparent, transparent),
-      linear-gradient(
-        to left,
-        var(--color-primary-lighter),
-        var(--color-primary-light)
-      ),
-      linear-gradient(to top, transparent, transparent);
-    background-position: top left, top right, bottom center, bottom left;
-    background-size: 0% var(--draw-border-thickness),
-      var(--draw-border-thickness) 0%, 60% var(--draw-border-thickness),
-      var(--draw-border-thickness) 0%;
-
-    &:hover,
-    &:focus {
-      --draw-border-color1: var(--color-primary-light);
-      --draw-border-color2: var(--color-primary-lighter);
-
-      @extend %draw-borders;
-    }
-
-    &:active {
-      --draw-border-color1: var(--color-primary-dark);
-      --draw-border-color2: var(--color-primary-light);
-
-      @extend %draw-borders;
-    }
-  }
-}
-
-.checkbox:not(:checked) {
-  ~ .nav {
-    opacity: 0;
-    visibility: hidden;
-    transform: translateY(100vw);
-
-    @include mix.media("screen") {
-      @include mix.dimensions("sm") {
-        transform: perspective(20rem) translate3d(0, 100%, -20rem);
-      }
-
-      @include mix.dimensions("md") {
-        opacity: 1;
-        visibility: visible;
-        transform: none;
-      }
-    }
-  }
-}
-
-.checkbox:checked {
-  ~ .label:hover {
-    span {
-      background: none;
-      box-shadow: none;
-    }
-  }
-
-  &:hover {
-    ~ .label {
-      span {
-        background: none;
-        box-shadow: none;
-      }
-    }
-  }
-}
diff --git a/src/components/MainNav/MainNav.tsx b/src/components/MainNav/MainNav.tsx
deleted file mode 100644
index 9cb6b4c..0000000
--- a/src/components/MainNav/MainNav.tsx
+++ /dev/null
@@ -1,155 +0,0 @@
-import {
-  BlogIcon,
-  ContactIcon,
-  CVIcon,
-  HamburgerIcon,
-  HomeIcon,
-  ProjectsIcon,
-} from '@components/Icons';
-import { NavItem } from '@ts/types/nav';
-import Link from 'next/link';
-import { useRouter } from 'next/router';
-import { ForwardedRef, forwardRef, SetStateAction } from 'react';
-import { useIntl } from 'react-intl';
-import styles from './MainNav.module.scss';
-
-const MainNav = (
-  {
-    isOpened,
-    setIsOpened,
-  }: {
-    isOpened: boolean;
-    setIsOpened: (value: SetStateAction<boolean>) => void;
-  },
-  ref: ForwardedRef<HTMLDivElement>
-) => {
-  const intl = useIntl();
-  const router = useRouter();
-
-  const mainNavConfig: NavItem[] = [
-    {
-      id: 'home',
-      name: intl.formatMessage({
-        defaultMessage: 'Home',
-        description: 'MainNav: home link',
-        id: 'ZJMNRW',
-      }),
-      slug: '/',
-    },
-    {
-      id: 'blog',
-      name: intl.formatMessage({
-        defaultMessage: 'Blog',
-        description: 'MainNav: blog link',
-        id: 'zPJifH',
-      }),
-      slug: '/blog',
-    },
-    {
-      id: 'projects',
-      name: intl.formatMessage({
-        defaultMessage: 'Projects',
-        description: 'MainNav: projects link',
-        id: 'akSutM',
-      }),
-      slug: '/projets',
-    },
-    {
-      id: 'cv',
-      name: intl.formatMessage({
-        defaultMessage: 'Resume',
-        description: 'MainNav: resume link',
-        id: 'jpv+Nz',
-      }),
-      slug: '/cv',
-    },
-    {
-      id: 'contact',
-      name: intl.formatMessage({
-        defaultMessage: 'Contact',
-        description: 'MainNav: contact link',
-        id: 'c2NtPj',
-      }),
-      slug: '/contact',
-    },
-  ];
-
-  const getIcon = (id: string) => {
-    switch (id) {
-      case 'home':
-        return <HomeIcon />;
-      case 'blog':
-        return <BlogIcon />;
-      case 'contact':
-        return <ContactIcon />;
-      case 'cv':
-        return <CVIcon />;
-      case 'projects':
-        return <ProjectsIcon />;
-      default:
-        break;
-    }
-  };
-
-  const navItems = mainNavConfig.map((item) => {
-    const currentClass = router.asPath === item.slug ? styles.current : '';
-
-    return (
-      <li key={item.id}>
-        <Link href={item.slug}>
-          <a className={`${styles.link} ${currentClass}`}>
-            {getIcon(item.id)}
-            <span>{item.name}</span>
-          </a>
-        </Link>
-      </li>
-    );
-  });
-
-  return (
-    <div id="main-nav" ref={ref} className={styles.wrapper}>
-      <input
-        type="checkbox"
-        name="main-nav__checkbox"
-        id="main-nav__checkbox"
-        aria-labelledby="main-nav-toggle"
-        className={styles.checkbox}
-        checked={isOpened}
-        onChange={() => setIsOpened(!isOpened)}
-        autoComplete="off"
-      />
-      <label
-        htmlFor="main-nav__checkbox"
-        id="main-nav-toggle"
-        className={styles.label}
-      >
-        <HamburgerIcon isActive={isOpened} />
-        <span className="screen-reader-text">
-          {isOpened
-            ? intl.formatMessage({
-                defaultMessage: 'Close menu',
-                description: 'MainNav: close button',
-                id: 'dE8xxV',
-              })
-            : intl.formatMessage({
-                defaultMessage: 'Open menu',
-                description: 'MainNav: open button',
-                id: 'azc1GT',
-              })}
-        </span>
-      </label>
-      <nav
-        className={styles.nav}
-        aria-label={intl.formatMessage({
-          defaultMessage: 'Primary',
-          description: 'MainNav: aria-label',
-          id: 'H7C5Bk',
-        })}
-      >
-        <ul className={styles.list}>{navItems}</ul>
-      </nav>
-    </div>
-  );
-};
-
-export default forwardRef(MainNav);
diff --git a/src/components/MetaItems/Author/Author.tsx b/src/components/MetaItems/Author/Author.tsx
deleted file mode 100644
index 4ff0086..0000000
--- a/src/components/MetaItems/Author/Author.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { MetaKind } from '@ts/types/app';
-import { useIntl } from 'react-intl';
-import { MetaItem } from '..';
-
-const Author = ({ name, kind }: { name: string; kind: MetaKind }) => {
-  const intl = useIntl();
-
-  return (
-    <MetaItem
-      title={intl.formatMessage({
-        defaultMessage: 'Written by:',
-        description: 'Author: article author meta label',
-        id: 'jCyqZS',
-      })}
-      value={name}
-      kind={kind}
-    />
-  );
-};
-
-export default Author;
diff --git a/src/components/MetaItems/CommentsCount/CommentsCount.tsx b/src/components/MetaItems/CommentsCount/CommentsCount.tsx
deleted file mode 100644
index 04cffa6..0000000
--- a/src/components/MetaItems/CommentsCount/CommentsCount.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { MetaKind } from '@ts/types/app';
-import { useRouter } from 'next/router';
-import { useIntl } from 'react-intl';
-import { MetaItem } from '..';
-
-const CommentsCount = ({ total, kind }: { total: number; kind: MetaKind }) => {
-  const intl = useIntl();
-  const { asPath } = useRouter();
-
-  const isArticle = () => asPath.includes('/article/');
-
-  const getCommentsCount = () => {
-    return intl.formatMessage(
-      {
-        defaultMessage:
-          '{total, plural, =0 {No comments} one {# comment} other {# comments}}',
-        description: 'CommentsCount: comment count value',
-        id: 'lKGNKx',
-      },
-      { total }
-    );
-  };
-
-  return (
-    <MetaItem
-      title={intl.formatMessage({
-        defaultMessage: 'Comments:',
-        description: 'CommentsCount: comment count meta label',
-        id: '6BRtAu',
-      })}
-      value={
-        isArticle() ? (
-          <a href="#comments">{getCommentsCount()}</a>
-        ) : (
-          getCommentsCount()
-        )
-      }
-      kind={kind}
-    />
-  );
-};
-
-export default CommentsCount;
diff --git a/src/components/MetaItems/Dates/Dates.tsx b/src/components/MetaItems/Dates/Dates.tsx
deleted file mode 100644
index 4314ed9..0000000
--- a/src/components/MetaItems/Dates/Dates.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import { MetaKind } from '@ts/types/app';
-import { settings } from '@utils/config';
-import { getFormattedDate } from '@utils/helpers/format';
-import { useRouter } from 'next/router';
-import { useIntl } from 'react-intl';
-import { MetaItem } from '..';
-
-const Dates = ({
-  publication,
-  update,
-  kind,
-}: {
-  publication: string;
-  update: string;
-  kind: MetaKind;
-}) => {
-  const intl = useIntl();
-  const { locale } = useRouter();
-  const validLocale = locale ? locale : settings.locales.defaultLocale;
-
-  const publicationDate = getFormattedDate(publication, validLocale);
-  const updateDate = getFormattedDate(update, validLocale);
-
-  return (
-    <>
-      <MetaItem
-        title={intl.formatMessage({
-          defaultMessage: 'Published on:',
-          description: 'Dates: publication date meta label',
-          id: '52Fev1',
-        })}
-        values={[
-          <time key={publication} dateTime={publication}>
-            {publicationDate}
-          </time>,
-        ]}
-        kind={kind}
-      />
-      {publicationDate !== updateDate && (
-        <MetaItem
-          title={intl.formatMessage({
-            defaultMessage: 'Updated on:',
-            description: 'Dates: update date meta label',
-            id: 'C+r/LF',
-          })}
-          values={[
-            <time key={update} dateTime={update}>
-              {updateDate}
-            </time>,
-          ]}
-          kind={kind}
-        />
-      )}
-    </>
-  );
-};
-
-export default Dates;
diff --git a/src/components/MetaItems/MetaItem/MetaItem.module.scss b/src/components/MetaItems/MetaItem/MetaItem.module.scss
deleted file mode 100644
index 0b159ca..0000000
--- a/src/components/MetaItems/MetaItem/MetaItem.module.scss
+++ /dev/null
@@ -1,18 +0,0 @@
-.wrapper--article {
-  display: flex;
-  flex-flow: row wrap;
-}
-
-.title--article {
-  margin-right: var(--spacing-2xs);
-  color: var(--color-fg-light);
-}
-
-.body--article {
-  &:not(:first-of-type) {
-    &::before {
-      content: "/";
-      margin: 0 var(--spacing-2xs);
-    }
-  }
-}
diff --git a/src/components/MetaItems/MetaItem/MetaItem.tsx b/src/components/MetaItems/MetaItem/MetaItem.tsx
deleted file mode 100644
index 5c51283..0000000
--- a/src/components/MetaItems/MetaItem/MetaItem.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import { MetaKind } from '@ts/types/app';
-import { ReactElement } from 'react';
-import styles from './MetaItem.module.scss';
-
-const MetaItem = ({
-  title,
-  value,
-  values,
-  info,
-  kind = 'list',
-}: {
-  title: string;
-  value?: ReactElement | string;
-  values?: ReactElement[] | string[];
-  info?: string;
-  kind: MetaKind;
-}) => {
-  return (
-    <div className={styles[`wrapper--${kind}`]}>
-      <dt className={styles[`title--${kind}`]}>{title}</dt>
-      {value && (
-        <dd className={styles[`body--${kind}`]} title={info}>
-          {value}
-        </dd>
-      )}
-      {values &&
-        values.map((currentValue, index) => (
-          <dd key={index} className={styles[`body--${kind}`]} title={info}>
-            {currentValue}
-          </dd>
-        ))}
-    </div>
-  );
-};
-
-export default MetaItem;
diff --git a/src/components/MetaItems/PostsCount/PostsCount.tsx b/src/components/MetaItems/PostsCount/PostsCount.tsx
deleted file mode 100644
index 679abcd..0000000
--- a/src/components/MetaItems/PostsCount/PostsCount.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { MetaKind } from '@ts/types/app';
-import { useIntl } from 'react-intl';
-import { MetaItem } from '..';
-
-const PostsCount = ({ total, kind }: { total: number; kind: MetaKind }) => {
-  const intl = useIntl();
-
-  return (
-    <MetaItem
-      title={intl.formatMessage({
-        defaultMessage: 'Total:',
-        description: 'PostCount: total found articles meta label',
-        id: 'p1zZ/Z',
-      })}
-      value={intl.formatMessage(
-        {
-          defaultMessage:
-            '{total, plural, =0 {No articles} one {# article} other {# articles}}',
-          description: 'PostCount: total found articles',
-          id: '4EMSLO',
-        },
-        { total }
-      )}
-      kind={kind}
-    />
-  );
-};
-
-export default PostsCount;
diff --git a/src/components/MetaItems/ReadingTime/ReadingTime.tsx b/src/components/MetaItems/ReadingTime/ReadingTime.tsx
deleted file mode 100644
index 79d6f3c..0000000
--- a/src/components/MetaItems/ReadingTime/ReadingTime.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import { MetaKind } from '@ts/types/app';
-import { useRouter } from 'next/router';
-import { useIntl } from 'react-intl';
-import { MetaItem } from '..';
-
-const ReadingTime = ({
-  time,
-  words,
-  kind,
-}: {
-  time: number;
-  words: number;
-  kind: MetaKind;
-}) => {
-  const intl = useIntl();
-  const { locale } = useRouter();
-
-  const getEstimation = () => {
-    if (time < 0) {
-      return intl.formatMessage({
-        defaultMessage: 'less than 1 minute',
-        description: 'ReadingTime: Reading time value',
-        id: 'ySsWZl',
-      });
-    }
-
-    return intl.formatMessage(
-      {
-        defaultMessage:
-          '{time, plural, =0 {# minutes} one {# minute} other {# minutes}}',
-        description: 'ReadingTime: reading time value',
-        id: 'wdqOpf',
-      },
-      { time }
-    );
-  };
-
-  return (
-    <MetaItem
-      title={intl.formatMessage({
-        defaultMessage: 'Reading time:',
-        description: 'ReadingTime: reading time meta label',
-        id: 'n0Gbod',
-      })}
-      value={getEstimation()}
-      info={intl.formatMessage(
-        {
-          defaultMessage: 'Approximately {number} words',
-          description: 'ReadingTime: number of words',
-          id: 'k7/SkN',
-        },
-        { number: words.toLocaleString(locale) }
-      )}
-      kind={kind}
-    />
-  );
-};
-
-export default ReadingTime;
diff --git a/src/components/MetaItems/Thematics/Thematics.tsx b/src/components/MetaItems/Thematics/Thematics.tsx
deleted file mode 100644
index e655c5d..0000000
--- a/src/components/MetaItems/Thematics/Thematics.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { MetaKind } from '@ts/types/app';
-import { ThematicPreview } from '@ts/types/taxonomies';
-import Link from 'next/link';
-import { useIntl } from 'react-intl';
-import { MetaItem } from '..';
-
-const Thematics = ({
-  list,
-  kind,
-}: {
-  list: ThematicPreview[];
-  kind: MetaKind;
-}) => {
-  const intl = useIntl();
-
-  const getThematics = () => {
-    return list.map((thematic) => {
-      return (
-        <Link key={thematic.databaseId} href={`/thematique/${thematic.slug}`}>
-          <a>{thematic.title}</a>
-        </Link>
-      );
-    });
-  };
-
-  return (
-    <MetaItem
-      title={intl.formatMessage(
-        {
-          defaultMessage:
-            '{thematicsCount, plural, =0 {Thematics:} one {Thematic:} other {Thematics:}}',
-          description: 'Thematics: thematics list meta label',
-          id: '1r4ujR',
-        },
-        { thematicsCount: list.length }
-      )}
-      values={getThematics()}
-      kind={kind}
-    />
-  );
-};
-
-export default Thematics;
diff --git a/src/components/MetaItems/Topics/Topics.tsx b/src/components/MetaItems/Topics/Topics.tsx
deleted file mode 100644
index d5d90f0..0000000
--- a/src/components/MetaItems/Topics/Topics.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { MetaKind } from '@ts/types/app';
-import { TopicPreview } from '@ts/types/taxonomies';
-import Link from 'next/link';
-import { useIntl } from 'react-intl';
-import { MetaItem } from '..';
-
-const Topics = ({ list, kind }: { list: TopicPreview[]; kind: MetaKind }) => {
-  const intl = useIntl();
-
-  const getTopics = () => {
-    return list.map((topic) => {
-      return (
-        <Link key={topic.databaseId} href={`/sujet/${topic.slug}`}>
-          <a>{topic.title}</a>
-        </Link>
-      );
-    });
-  };
-
-  return (
-    <MetaItem
-      title={intl.formatMessage(
-        {
-          defaultMessage:
-            '{topicsCount, plural, =0 {Topics:} one {Topic:} other {Topics:}}',
-          description: 'Topics: topics list meta label',
-          id: '0pp/IQ',
-        },
-        { topicsCount: list.length }
-      )}
-      values={getTopics()}
-      kind={kind}
-    />
-  );
-};
-
-export default Topics;
diff --git a/src/components/MetaItems/Website/Website.tsx b/src/components/MetaItems/Website/Website.tsx
deleted file mode 100644
index 7d2dc06..0000000
--- a/src/components/MetaItems/Website/Website.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { MetaKind } from '@ts/types/app';
-import { useIntl } from 'react-intl';
-import { MetaItem } from '..';
-
-const Website = ({ url, kind }: { url: string; kind: MetaKind }) => {
-  const intl = useIntl();
-
-  return (
-    <MetaItem
-      title={intl.formatMessage({
-        defaultMessage: 'Website:',
-        description: 'Website: website meta label',
-        id: 'JsOoAW',
-      })}
-      value={<a href={url}>{url}</a>}
-      kind={kind}
-    />
-  );
-};
-
-export default Website;
diff --git a/src/components/MetaItems/index.tsx b/src/components/MetaItems/index.tsx
deleted file mode 100644
index e90d5a6..0000000
--- a/src/components/MetaItems/index.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import Author from './Author/Author';
-import CommentsCount from './CommentsCount/CommentsCount';
-import Dates from './Dates/Dates';
-import MetaItem from './MetaItem/MetaItem';
-import PostsCount from './PostsCount/PostsCount';
-import ReadingTime from './ReadingTime/ReadingTime';
-import Thematics from './Thematics/Thematics';
-import Topics from './Topics/Topics';
-import Website from './Website/Website';
-
-export {
-  Author,
-  CommentsCount,
-  Dates,
-  MetaItem,
-  PostsCount,
-  ReadingTime,
-  Thematics,
-  Topics,
-  Website,
-};
diff --git a/src/components/Notice/Notice.module.scss b/src/components/Notice/Notice.module.scss
deleted file mode 100644
index aa7175c..0000000
--- a/src/components/Notice/Notice.module.scss
+++ /dev/null
@@ -1,28 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.message {
-  border: fun.convert-px(2) solid;
-  font-weight: bold;
-  margin: var(--spacing-sm) auto;
-  padding: var(--spacing-2xs) var(--spacing-xs);
-
-  &--error {
-    border-color: var(--color-token-red);
-    color: var(--color-token-red);
-  }
-
-  &--info {
-    border-color: var(--color-token-blue);
-    color: var(--color-token-blue);
-  }
-
-  &--success {
-    border-color: var(--color-token-green);
-    color: var(--color-token-green);
-  }
-
-  &--warning {
-    border-color: var(--color-token-orange);
-    color: var(--color-token-orange);
-  }
-}
diff --git a/src/components/Notice/Notice.tsx b/src/components/Notice/Notice.tsx
deleted file mode 100644
index 02b1f12..0000000
--- a/src/components/Notice/Notice.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { NoticeType } from '@ts/types/app';
-import { ReactNode } from 'react';
-import styles from './Notice.module.scss';
-
-const Notice = ({
-  children,
-  type,
-}: {
-  children: ReactNode;
-  type: NoticeType;
-}) => {
-  const withModifier = `message--${type}`;
-
-  return (
-    <div className={`${styles.message} ${styles[withModifier]}`}>
-      {children}
-    </div>
-  );
-};
-
-export default Notice;
diff --git a/src/components/Pagination/Pagination.module.scss b/src/components/Pagination/Pagination.module.scss
deleted file mode 100644
index 4d74d1b..0000000
--- a/src/components/Pagination/Pagination.module.scss
+++ /dev/null
@@ -1,92 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-@use "@styles/abstracts/placeholders";
-
-.list {
-  @extend %flex-list;
-  justify-content: center;
-
-  row-gap: var(--spacing-sm);
-}
-
-.link {
-  display: block;
-  padding: var(--spacing-xs) var(--spacing-sm);
-  background: var(--color-bg);
-  border: fun.convert-px(2) solid var(--color-primary);
-  box-shadow: fun.convert-px(2) fun.convert-px(2) 0 0
-    var(--color-primary-darker);
-  font-weight: 600;
-  text-decoration: none;
-
-  @include mix.pointer("fine") {
-    padding: var(--spacing-2xs) var(--spacing-xs);
-  }
-
-  &--current {
-    padding: calc(var(--spacing-xs) / 1.5) var(--spacing-sm);
-    border-color: var(--color-primary-darker);
-    box-shadow: none;
-    color: var(--color-primary-darker);
-    transform: translateY(#{fun.convert-px(10)});
-
-    @include mix.pointer("fine") {
-      padding: calc(var(--spacing-2xs) / 1.5) var(--spacing-xs);
-      transform: translateY(#{fun.convert-px(7)});
-    }
-  }
-
-  &:not(.link--current) {
-    &:hover,
-    &:focus {
-      border-color: var(--color-primary-light);
-      box-shadow: fun.convert-px(2) fun.convert-px(2) 0 0
-          var(--color-primary-darker),
-        0 fun.convert-px(2) fun.convert-px(2) fun.convert-px(1)
-          var(--color-shadow-dark),
-        0 fun.convert-px(7) fun.convert-px(7) fun.convert-px(2)
-          var(--color-shadow-light);
-      color: var(--color-primary-light);
-      transform: translateY(#{fun.convert-px(-5)});
-    }
-
-    &:active {
-      padding: calc(var(--spacing-xs) / 1.5) var(--spacing-sm);
-      border-color: var(--color-primary-dark);
-      box-shadow: none;
-      color: var(--color-primary-dark);
-      transform: translateY(#{fun.convert-px(10)});
-
-      @include mix.pointer("fine") {
-        padding: calc(var(--spacing-2xs) / 1.5) var(--spacing-xs);
-        transform: translateY(#{fun.convert-px(7)});
-      }
-    }
-  }
-}
-
-.item {
-  position: relative;
-
-  &:first-child {
-    .link {
-      border-top-left-radius: fun.convert-px(4);
-      border-bottom-left-radius: fun.convert-px(4);
-    }
-  }
-
-  &:last-child {
-    .link {
-      border-top-right-radius: fun.convert-px(4);
-      border-bottom-right-radius: fun.convert-px(4);
-    }
-  }
-
-  &:not(:first-child) {
-    margin-left: fun.convert-px(-1);
-  }
-
-  &:not(:last-child) {
-    margin-right: fun.convert-px(-1);
-  }
-}
diff --git a/src/components/Pagination/Pagination.tsx b/src/components/Pagination/Pagination.tsx
deleted file mode 100644
index 55c366a..0000000
--- a/src/components/Pagination/Pagination.tsx
+++ /dev/null
@@ -1,136 +0,0 @@
-import { settings } from '@utils/config';
-import Link from 'next/link';
-import { useRouter } from 'next/router';
-import { useIntl } from 'react-intl';
-import styles from './Pagination.module.scss';
-
-const Pagination = ({ baseUrl, total }: { baseUrl: string; total: number }) => {
-  const intl = useIntl();
-  const { asPath } = useRouter();
-  const totalPages = Math.floor(total / settings.postsPerPage);
-  const currentPage = asPath.includes('/page/')
-    ? Number(asPath.split(`${baseUrl}/page/`)[1])
-    : 1;
-  const hasPreviousPage = currentPage !== 1;
-  const hasNextPage = currentPage !== totalPages;
-
-  const getPreviousPageItem = () => {
-    return (
-      <li className={styles.item}>
-        <Link href={`${baseUrl}/page/${currentPage - 1}`}>
-          <a className={styles.link}>
-            {intl.formatMessage(
-              {
-                defaultMessage: '{icon} Previous page',
-                description: 'Pagination: previous page link',
-                id: 'aMFqPH',
-              },
-              { icon: '←' }
-            )}
-          </a>
-        </Link>
-      </li>
-    );
-  };
-
-  const getNextPageItem = () => {
-    return (
-      <li className={styles.item}>
-        <Link href={`${baseUrl}/page/${currentPage + 1}`}>
-          <a className={styles.link}>
-            {intl.formatMessage(
-              {
-                defaultMessage: 'Next page {icon}',
-                description: 'Pagination: Next page link',
-                id: 'R4yaW6',
-              },
-              { icon: '→' }
-            )}
-          </a>
-        </Link>
-      </li>
-    );
-  };
-
-  const getPages = () => {
-    const pages = [];
-    for (let i = 1; i <= totalPages; i++) {
-      if (i === currentPage) {
-        pages.push({
-          id: `page-${i}`,
-          link: (
-            <span className={`${styles.link} ${styles['link--current']}`}>
-              {intl.formatMessage(
-                {
-                  defaultMessage: '<a11y>Page </a11y>{number}',
-                  description: 'Pagination: page number',
-                  id: 'TSXPzr',
-                },
-                {
-                  number: i,
-                  a11y: (chunks: string) => (
-                    <span className="screen-reader-text">{chunks}</span>
-                  ),
-                }
-              )}
-            </span>
-          ),
-        });
-      } else {
-        pages.push({
-          id: `page-${i}`,
-          link: (
-            <Link href={`${baseUrl}/page/${i}`}>
-              <a className={styles.link}>
-                {intl.formatMessage(
-                  {
-                    defaultMessage: '<a11y>Page </a11y>{number}',
-                    description: 'Pagination: page number',
-                    id: 'TSXPzr',
-                  },
-                  {
-                    number: i,
-                    a11y: (chunks: string) => (
-                      <span className="screen-reader-text">{chunks}</span>
-                    ),
-                  }
-                )}
-              </a>
-            </Link>
-          ),
-        });
-      }
-    }
-
-    return pages;
-  };
-
-  const getItems = () => {
-    const pages = getPages();
-
-    return pages.map((page) => (
-      <li key={page.id} className={styles.item}>
-        {page.link}
-      </li>
-    ));
-  };
-
-  return (
-    <nav className={styles.wrapper} aria-labelledby="pagination-title">
-      <h2 id="pagination-title" className="screen-reader-text">
-        {intl.formatMessage({
-          defaultMessage: 'Pagination',
-          description: 'Pagination: pagination title',
-          id: 'BAkq7J',
-        })}
-      </h2>
-      <ul className={styles.list}>
-        {hasPreviousPage && getPreviousPageItem()}
-        {getItems()}
-        {hasNextPage && getNextPageItem()}
-      </ul>
-    </nav>
-  );
-};
-
-export default Pagination;
diff --git a/src/components/PaginationCursor/PaginationCursor.module.scss b/src/components/PaginationCursor/PaginationCursor.module.scss
deleted file mode 100644
index 542584c..0000000
--- a/src/components/PaginationCursor/PaginationCursor.module.scss
+++ /dev/null
@@ -1,43 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.wrapper {
-  width: max-content;
-  margin: var(--spacing-sm) auto var(--spacing-md);
-  text-align: center;
-
-  .bar[value] {
-    display: block;
-    width: clamp(25ch, 20vw, 30ch);
-    max-width: 100%;
-    height: fun.convert-px(13);
-    appearance: none;
-    background: var(--color-bg-tertiary);
-    border: fun.convert-px(1) solid var(--color-primary-darker);
-    border-radius: 1em;
-    box-shadow: inset 0 0 fun.convert-px(4) fun.convert-px(1)
-      var(--color-shadow-light);
-
-    &::-webkit-progress-value {
-      background-color: var(--color-primary-dark);
-      border-radius: 1em;
-    }
-
-    &::-moz-progress-bar {
-      background-color: var(--color-primary-dark);
-      border-radius: 1em;
-    }
-
-    &::-webkit-progress-bar {
-      background: var(--color-bg-tertiary);
-      border: fun.convert-px(1) solid var(--color-primary-darker);
-      border-radius: 1em;
-      box-shadow: inset 0 0 fun.convert-px(4) fun.convert-px(1)
-        var(--color-shadow-light);
-    }
-  }
-}
-
-.info {
-  margin-bottom: var(--spacing-2xs);
-  font-size: var(--font-size-sm);
-}
diff --git a/src/components/PaginationCursor/PaginationCursor.tsx b/src/components/PaginationCursor/PaginationCursor.tsx
deleted file mode 100644
index d64f961..0000000
--- a/src/components/PaginationCursor/PaginationCursor.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { useIntl } from 'react-intl';
-import styles from './PaginationCursor.module.scss';
-
-const PaginationCursor = ({
-  current,
-  total,
-}: {
-  current: number;
-  total: number;
-}) => {
-  const intl = useIntl();
-
-  return (
-    <div className={styles.wrapper}>
-      <div className={styles.info}>
-        {intl.formatMessage(
-          {
-            defaultMessage:
-              '{articlesCount, plural, =0 {# loaded articles} one {# loaded article} other {# loaded articles}} out of a total of {total}',
-            description: 'PaginationCursor: loaded articles count message',
-            id: 'du4MLN',
-          },
-          { articlesCount: current, total }
-        )}
-      </div>
-      <progress
-        className={styles.bar}
-        max={total}
-        value={current}
-        aria-valuemin={0}
-        aria-valuemax={total}
-        aria-label={intl.formatMessage({
-          defaultMessage:
-            'Number of articles loaded out of the total available.',
-          description: 'PaginationCursor: loaded articles count aria-label',
-          id: 'mC21ht',
-        })}
-      ></progress>
-    </div>
-  );
-};
-
-export default PaginationCursor;
diff --git a/src/components/PostFooter/PostFooter.module.scss b/src/components/PostFooter/PostFooter.module.scss
deleted file mode 100644
index 7c1f1ce..0000000
--- a/src/components/PostFooter/PostFooter.module.scss
+++ /dev/null
@@ -1,18 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/placeholders";
-
-.meta {
-  flex-flow: column wrap;
-}
-
-.list {
-  @extend %flex-list;
-
-  gap: var(--spacing-xs);
-}
-
-.item {
-  > a {
-    padding: calc(var(--spacing-2xs) / 2) var(--spacing-xs);
-  }
-}
diff --git a/src/components/PostFooter/PostFooter.tsx b/src/components/PostFooter/PostFooter.tsx
deleted file mode 100644
index 9bc4053..0000000
--- a/src/components/PostFooter/PostFooter.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import { ButtonLink } from '@components/Buttons';
-import { TopicPreview } from '@ts/types/taxonomies';
-import Image from 'next/image';
-import { useIntl } from 'react-intl';
-import styles from './PostFooter.module.scss';
-
-const PostFooter = ({ topics }: { topics: TopicPreview[] }) => {
-  const intl = useIntl();
-
-  const getTopics = () => {
-    return topics.map((topic) => {
-      return (
-        <li className={styles.item} key={topic.id}>
-          <ButtonLink target={`/sujet/${topic.slug}`}>
-            {topic.featuredImage && (
-              <Image
-                src={topic.featuredImage.sourceUrl}
-                alt={topic.featuredImage.altText}
-                layout="intrinsic"
-                width="20"
-                height="20"
-              />
-            )}
-            {topic.title}
-          </ButtonLink>
-        </li>
-      );
-    });
-  };
-
-  return (
-    <footer>
-      {topics.length > 0 && (
-        <>
-          <dl className={styles.meta}>
-            <dt>
-              {intl.formatMessage({
-                defaultMessage: 'Read more articles about:',
-                description: 'PostFooter: read more posts about given subjects',
-                id: 'YEudoh',
-              })}
-            </dt>
-            <dd>
-              <ul className={styles.list}>{getTopics()}</ul>
-            </dd>
-          </dl>
-        </>
-      )}
-    </footer>
-  );
-};
-
-export default PostFooter;
diff --git a/src/components/PostHeader/PostHeader.module.scss b/src/components/PostHeader/PostHeader.module.scss
deleted file mode 100644
index f813060..0000000
--- a/src/components/PostHeader/PostHeader.module.scss
+++ /dev/null
@@ -1,83 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-
-.wrapper {
-  composes: grid from "@styles/layout/_grid.scss";
-  max-width: 100%;
-  position: relative;
-
-  @include mix.media("screen") {
-    @include mix.dimensions("md") {
-      margin-bottom: var(--spacing-md);
-    }
-
-    @include mix.dimensions("lg") {
-      --grid-gap: var(--spacing-lg);
-    }
-  }
-
-  &::before,
-  &::after {
-    content: "";
-    width: 100%;
-    height: 100%;
-    background: var(--color-bg-secondary);
-    border-top: fun.convert-px(3) solid var(--color-border-light);
-    border-bottom: fun.convert-px(3) solid var(--color-border-light);
-  }
-
-  &::before {
-    grid-column: 1;
-    justify-self: start;
-    border-right: fun.convert-px(3) solid var(--color-border-light);
-  }
-
-  &::after {
-    grid-column: 3;
-    justify-self: end;
-    border-left: fun.convert-px(3) solid var(--color-border-light);
-  }
-}
-
-.body {
-  grid-column: 2;
-  background: var(--color-bg);
-}
-
-.title {
-  flex: 0 0 100%;
-  display: flex;
-  flex-flow: row wrap;
-  align-items: center;
-  margin: 0;
-  position: relative;
-  text-shadow: fun.convert-px(1) fun.convert-px(1) 0 var(--color-shadow-light);
-
-  &::before,
-  &::after {
-    content: "";
-    width: 100%;
-    height: fun.convert-px(4);
-    background: radial-gradient(
-      ellipse at center,
-      var(--color-primary-light),
-      var(--color-primary-dark)
-    );
-  }
-}
-
-.cover {
-  display: block;
-  width: fun.convert-px(50);
-  height: fun.convert-px(50);
-  position: relative;
-  margin-right: var(--spacing-sm);
-}
-
-.intro {
-  margin: var(--spacing-sm) 0 0;
-
-  > *:last-child {
-    margin-bottom: 0;
-  }
-}
diff --git a/src/components/PostHeader/PostHeader.tsx b/src/components/PostHeader/PostHeader.tsx
deleted file mode 100644
index c0a6b68..0000000
--- a/src/components/PostHeader/PostHeader.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import PostMeta from '@components/PostMeta/PostMeta';
-import { ArticleMeta } from '@ts/types/articles';
-import { Cover } from '@ts/types/cover';
-import Image from 'next/image';
-import React, { ReactElement } from 'react';
-import styles from './PostHeader.module.scss';
-
-const PostHeader = ({
-  cover,
-  intro,
-  title,
-  meta,
-}: {
-  cover?: Cover;
-  intro?: string | ReactElement;
-  meta?: ArticleMeta;
-  title: string;
-}) => {
-  const getIntro = () => {
-    if (React.isValidElement(intro)) {
-      const Intro = () => intro;
-      return (
-        <div className={styles.intro}>
-          <Intro />
-        </div>
-      );
-    }
-
-    return (
-      intro && (
-        <div
-          className={styles.intro}
-          dangerouslySetInnerHTML={{ __html: intro }}
-        ></div>
-      )
-    );
-  };
-
-  return (
-    <header className={styles.wrapper}>
-      <div className={styles.body}>
-        <h1 className={styles.title}>
-          {cover && (
-            <span className={styles.cover}>
-              <Image src={cover.sourceUrl} alt={cover.altText} layout="fill" />
-            </span>
-          )}
-          {title}
-        </h1>
-        {meta && <PostMeta kind="article" meta={meta} />}
-        {getIntro()}
-      </div>
-    </header>
-  );
-};
-
-export default PostHeader;
diff --git a/src/components/PostMeta/PostMeta.module.scss b/src/components/PostMeta/PostMeta.module.scss
deleted file mode 100644
index d438635..0000000
--- a/src/components/PostMeta/PostMeta.module.scss
+++ /dev/null
@@ -1,31 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-
-.wrapper {
-  &--list {
-    display: grid;
-    grid-template-columns: repeat(2, minmax(0, 1fr));
-    margin-top: var(--spacing-md);
-    font-size: var(--font-size-sm);
-
-    @include mix.media("screen") {
-      @include mix.dimensions("sm") {
-        display: flex;
-        flex-flow: column nowrap;
-        margin: 0;
-        composes: meta from "@components/PostPreview/PostPreview.module.scss";
-      }
-    }
-  }
-
-  &--article {
-    flex-flow: column wrap;
-    margin: var(--spacing-sm) 0 0;
-
-    @include mix.media("screen") {
-      @include mix.dimensions("xs") {
-        font-size: var(--font-size-sm);
-      }
-    }
-  }
-}
diff --git a/src/components/PostMeta/PostMeta.tsx b/src/components/PostMeta/PostMeta.tsx
deleted file mode 100644
index 7fba0be..0000000
--- a/src/components/PostMeta/PostMeta.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import {
-  Author,
-  CommentsCount,
-  Dates,
-  PostsCount,
-  ReadingTime,
-  Thematics,
-  Topics,
-  Website,
-} from '@components/MetaItems';
-import { MetaKind } from '@ts/types/app';
-import { ArticleMeta } from '@ts/types/articles';
-import { useRouter } from 'next/router';
-import styles from './PostMeta.module.scss';
-
-const PostMeta = ({
-  meta,
-  kind = 'list',
-}: {
-  meta: ArticleMeta;
-  kind?: MetaKind;
-}) => {
-  const {
-    author,
-    commentCount,
-    dates,
-    readingTime,
-    results,
-    thematics,
-    topics,
-    website,
-    wordsCount,
-  } = meta;
-  const { asPath } = useRouter();
-  const isThematic = () => asPath.includes('/thematique/');
-
-  const wrapperClass = styles[`wrapper--${kind}`];
-
-  return (
-    <dl className={wrapperClass}>
-      {author && <Author name={author.name} kind={kind} />}
-      {dates && (
-        <Dates
-          publication={dates.publication}
-          update={dates.update}
-          kind={kind}
-        />
-      )}
-      {readingTime !== undefined && wordsCount !== undefined && (
-        <ReadingTime time={readingTime} words={wordsCount} kind={kind} />
-      )}
-      {results !== undefined && <PostsCount total={results} kind={kind} />}
-      {!isThematic() && thematics && thematics.length > 0 && (
-        <Thematics list={thematics} kind={kind} />
-      )}
-      {isThematic() && topics && topics.length > 0 && (
-        <Topics list={topics} kind={kind} />
-      )}
-      {website && <Website url={website} kind={kind} />}
-      {commentCount !== undefined && (
-        <CommentsCount total={commentCount} kind={kind} />
-      )}
-    </dl>
-  );
-};
-
-export default PostMeta;
diff --git a/src/components/PostPreview/PostPreview.module.scss b/src/components/PostPreview/PostPreview.module.scss
deleted file mode 100644
index c30ab75..0000000
--- a/src/components/PostPreview/PostPreview.module.scss
+++ /dev/null
@@ -1,105 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-
-.wrapper {
-  --icon-size: #{fun.convert-px(20)};
-
-  padding: var(--spacing-2xs) 0 var(--spacing-lg);
-  transition: all 0.3s ease-in-out 0s, border 0s;
-
-  &:hover {
-    --icon-size: #{fun.convert-px(25)};
-
-    a {
-      > svg {
-        :global {
-          animation: pulse 1.5s ease-in-out 0.5s infinite;
-        }
-      }
-
-      &:hover {
-        > svg {
-          animation: none;
-        }
-      }
-    }
-  }
-
-  &:active {
-    --icon-size: 0;
-  }
-}
-
-.cover {
-  width: auto;
-  height: fun.convert-px(100);
-  margin: 0 auto var(--spacing-sm);
-  position: relative;
-  border: fun.convert-px(1) solid var(--color-border);
-}
-
-h2.title {
-  background: none;
-  text-shadow: none;
-}
-
-@include mix.media("screen") {
-  @include mix.dimensions("xs") {
-    .wrapper {
-      margin: 0;
-      padding: var(--spacing-sm) var(--spacing-sm) var(--spacing-md);
-      border: fun.convert-px(1) solid var(--color-primary-dark);
-      border-radius: fun.convert-px(3);
-      box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1) 0
-          var(--color-shadow),
-        fun.convert-px(3) fun.convert-px(3) fun.convert-px(3) fun.convert-px(-1)
-          var(--color-shadow-light),
-        fun.convert-px(5) fun.convert-px(5) fun.convert-px(7) fun.convert-px(-1)
-          var(--color-shadow-light);
-    }
-
-    .read-more {
-      font-size: var(--font-size-sm);
-    }
-  }
-
-  @include mix.dimensions("sm") {
-    .wrapper {
-      display: grid;
-      grid-template-columns: minmax(0, 3fr) minmax(0, 1fr);
-      grid-template-rows: repeat(3, max-content);
-      column-gap: var(--spacing-md);
-    }
-
-    .cover {
-      grid-column: 2;
-      grid-row: 1;
-      margin: 0 0 var(--spacing-sm);
-    }
-
-    .header {
-      grid-column: 1;
-      grid-row: 1;
-      align-self: center;
-    }
-
-    .meta {
-      grid-column: 2;
-      grid-row: 2 / 4;
-    }
-
-    .body {
-      grid-column: 1;
-      grid-row: 2;
-    }
-
-    .footer {
-      grid-column: 1;
-      grid-row: 3;
-    }
-
-    .read-more {
-      margin: 0;
-    }
-  }
-}
diff --git a/src/components/PostPreview/PostPreview.tsx b/src/components/PostPreview/PostPreview.tsx
deleted file mode 100644
index 0b9e332..0000000
--- a/src/components/PostPreview/PostPreview.tsx
+++ /dev/null
@@ -1,120 +0,0 @@
-import { ButtonLink } from '@components/Buttons';
-import { ArrowIcon } from '@components/Icons';
-import PostMeta from '@components/PostMeta/PostMeta';
-import { TitleLevel } from '@ts/types/app';
-import { ArticleMeta, ArticlePreview } from '@ts/types/articles';
-import { settings } from '@utils/config';
-import Image from 'next/image';
-import Link from 'next/link';
-import { FormattedMessage } from 'react-intl';
-import { BlogPosting, WithContext } from 'schema-dts';
-import styles from './PostPreview.module.scss';
-import Script from 'next/script';
-
-const PostPreview = ({
-  post,
-  titleLevel,
-}: {
-  post: ArticlePreview;
-  titleLevel: TitleLevel;
-}) => {
-  const TitleTag = `h${titleLevel}` as keyof JSX.IntrinsicElements;
-  const {
-    commentCount,
-    dates,
-    featuredImage,
-    info,
-    intro,
-    slug,
-    thematics,
-    title,
-    topics,
-  } = post;
-
-  const meta: ArticleMeta = {
-    commentCount: commentCount ? commentCount : 0,
-    dates: dates,
-    readingTime: info.readingTime,
-    thematics: thematics,
-    topics: topics,
-    wordsCount: info.wordsCount,
-  };
-
-  const publicationDate = new Date(dates.publication);
-  const updateDate = new Date(dates.update);
-
-  const schemaJsonLd: WithContext<BlogPosting> = {
-    '@context': 'https://schema.org',
-    '@type': 'BlogPosting',
-    name: title,
-    description: intro,
-    articleBody: intro,
-    author: { '@id': `${settings.url}/#branding` },
-    commentCount: commentCount ? commentCount : 0,
-    copyrightYear: publicationDate.getFullYear(),
-    creator: { '@id': `${settings.url}/#branding` },
-    dateCreated: publicationDate.toISOString(),
-    dateModified: updateDate.toISOString(),
-    datePublished: publicationDate.toISOString(),
-    editor: { '@id': `${settings.url}/#branding` },
-    headline: title,
-    image: featuredImage?.sourceUrl,
-    inLanguage: settings.locales.defaultLocale,
-    isBasedOn: `${settings.url}/article/${slug}`,
-    isPartOf: { '@id': `${settings.url}/blog` },
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-    thumbnailUrl: featuredImage?.sourceUrl,
-  };
-
-  return (
-    <>
-      <Script
-        id="schema-post-preview"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      <article className={styles.wrapper}>
-        {featuredImage && Object.keys(featuredImage).length > 0 && (
-          <div className={styles.cover}>
-            <Image
-              src={featuredImage.sourceUrl}
-              alt={featuredImage.altText}
-              layout="fill"
-              objectFit="contain"
-            />
-          </div>
-        )}
-        <header className={styles.header}>
-          <TitleTag className={styles.title}>
-            <Link href={`/article/${slug}`}>
-              <a>{title}</a>
-            </Link>
-          </TitleTag>
-        </header>
-        <div
-          className={styles.body}
-          dangerouslySetInnerHTML={{ __html: intro }}
-        ></div>
-        <footer className={styles.footer}>
-          <ButtonLink target={`/article/${slug}`} position="left">
-            <FormattedMessage
-              defaultMessage="Read more<a11y> about {title}</a11y>"
-              description="PostPreview: read more link"
-              id="bkbrN7"
-              values={{
-                title,
-                a11y: (chunks: string) => (
-                  <span className="screen-reader-text">{chunks}</span>
-                ),
-              }}
-            />
-            <ArrowIcon />
-          </ButtonLink>
-        </footer>
-        <PostMeta meta={meta} />
-      </article>
-    </>
-  );
-};
-
-export default PostPreview;
diff --git a/src/components/PostsList/PostsList.module.scss b/src/components/PostsList/PostsList.module.scss
deleted file mode 100644
index b4ffbd9..0000000
--- a/src/components/PostsList/PostsList.module.scss
+++ /dev/null
@@ -1,51 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-@use "@styles/abstracts/placeholders";
-
-.section {
-  --column-3: 0;
-  --grid-gap: 0;
-
-  composes: grid from "@styles/layout/_grid.scss";
-  align-items: first baseline;
-}
-
-.year {
-  grid-column: 2;
-  margin: var(--spacing-md) 0 0;
-
-  @include mix.media("screen") {
-    @include mix.dimensions("md") {
-      grid-column: 1;
-      justify-self: end;
-      position: sticky;
-      top: var(--spacing-xs);
-      margin-right: var(--spacing-lg);
-    }
-  }
-}
-
-.list {
-  @extend %reset-ordered-list;
-
-  grid-column: 2;
-  margin: 0 auto var(--spacing-md);
-}
-
-li.item {
-  border-bottom: fun.convert-px(1) solid var(--color-border);
-
-  &:not(:last-of-type) {
-    margin: 0 0 var(--spacing-md) 0;
-  }
-
-  &:first-of-type {
-    margin-top: var(--spacing-sm);
-
-    @include mix.media("screen") {
-      @include mix.dimensions("md") {
-        margin-top: 0;
-      }
-    }
-  }
-}
diff --git a/src/components/PostsList/PostsList.tsx b/src/components/PostsList/PostsList.tsx
deleted file mode 100644
index f998846..0000000
--- a/src/components/PostsList/PostsList.tsx
+++ /dev/null
@@ -1,110 +0,0 @@
-import PostPreview from '@components/PostPreview/PostPreview';
-import { PostsList as PostsListData } from '@ts/types/blog';
-import { sortPostsByYear } from '@utils/helpers/sort';
-import { ForwardedRef, forwardRef, Fragment } from 'react';
-import { useIntl } from 'react-intl';
-import styles from './PostsList.module.scss';
-
-const PostsList = (
-  {
-    data,
-    showYears,
-  }: {
-    data: PostsListData[];
-    showYears: boolean;
-  },
-  ref: ForwardedRef<HTMLSpanElement>
-) => {
-  const intl = useIntl();
-  const titleLevel = showYears ? 3 : 2;
-
-  const getPostsListByYear = () => {
-    const posts = sortPostsByYear(data);
-    const years = Object.keys(posts).reverse();
-
-    const getLastPostId = () => {
-      const oldestYear = Object.keys(posts)[0];
-      const lastPost = posts[oldestYear][posts[oldestYear].length - 1];
-      return lastPost.id;
-    };
-
-    return years.map((year) => {
-      return (
-        <section key={year} className={styles.section}>
-          {showYears && (
-            <h2 className={styles.year}>
-              <span className="screen-reader-text">
-                {intl.formatMessage({
-                  defaultMessage: 'Published on',
-                  description: 'PostsList: published on year label',
-                  id: 'EvODgw',
-                })}{' '}
-              </span>
-              {year}
-            </h2>
-          )}
-          <ol className={styles.list}>
-            {posts[year].map((post) => {
-              const isLastPost = post.id === getLastPostId();
-              return (
-                <Fragment key={post.id}>
-                  <li className={styles.item}>
-                    <PostPreview post={post} titleLevel={titleLevel} />
-                  </li>
-                  {isLastPost && (
-                    <li className={styles.item}>
-                      <span ref={ref} tabIndex={-1} />
-                    </li>
-                  )}
-                </Fragment>
-              );
-            })}
-          </ol>
-        </section>
-      );
-    });
-  };
-
-  const getPostsList = () => {
-    return data.map((page) => {
-      const getLastPostId = () => {
-        const lastPost = page.posts[page.posts.length - 1];
-        return lastPost.id;
-      };
-
-      if (page.posts.length === 0) {
-        return (
-          <p key="no-result">
-            {intl.formatMessage({
-              defaultMessage: 'No results found.',
-              description: 'PostsList: no results',
-              id: 'vK7Sxv',
-            })}
-          </p>
-        );
-      } else {
-        return (
-          <Fragment key={page.pageInfo.endCursor}>
-            <ol className={styles.list}>
-              {page.posts.map((post) => {
-                const isLastPost = post.id === getLastPostId();
-                return (
-                  <Fragment key={post.id}>
-                    <li key={post.id} className={styles.item}>
-                      <PostPreview post={post} titleLevel={titleLevel} />
-                    </li>
-                    {isLastPost && <span ref={ref} tabIndex={-1} />}
-                  </Fragment>
-                );
-              })}
-            </ol>
-          </Fragment>
-        );
-      }
-    });
-  };
-
-  return <div>{showYears ? getPostsListByYear() : getPostsList()}</div>;
-};
-
-export default forwardRef(PostsList);
diff --git a/src/components/ProjectPreview/ProjectPreview.module.scss b/src/components/ProjectPreview/ProjectPreview.module.scss
deleted file mode 100644
index 3bf56ec..0000000
--- a/src/components/ProjectPreview/ProjectPreview.module.scss
+++ /dev/null
@@ -1,98 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.article {
-  display: flex;
-  flex-flow: column nowrap;
-  height: 100%;
-  padding: var(--spacing-md);
-  text-align: center;
-}
-
-.cover {
-  height: fun.convert-px(150);
-  position: relative;
-}
-
-.title {
-  flex: 1;
-  margin: var(--spacing-xs) 0;
-  background: none;
-  text-decoration: underline solid transparent 0;
-  text-shadow: none;
-  transition: all 0.3s linear 0s;
-}
-
-.body {
-  margin: 0 0 var(--spacing-xs);
-}
-
-.footer {
-  margin-top: auto;
-}
-
-.meta {
-  display: block;
-
-  &__item {
-    display: flex;
-    flex-flow: row wrap;
-    place-content: center;
-    gap: var(--spacing-2xs);
-  }
-}
-
-.link {
-  display: block;
-  height: 100%;
-  background: var(--color-bg);
-  color: inherit;
-  text-decoration: none;
-  border: fun.convert-px(3) solid var(--color-primary);
-  border-radius: fun.convert-px(5);
-  box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1)
-      var(--color-shadow),
-    fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-2)
-      var(--color-shadow),
-    fun.convert-px(3) fun.convert-px(4) fun.convert-px(5) fun.convert-px(-4)
-      var(--color-shadow);
-  transition: all 0.3s ease-in-out 0s;
-
-  &:hover,
-  &:focus,
-  &:active {
-    color: inherit;
-  }
-
-  &:hover,
-  &:focus {
-    box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1)
-        var(--color-shadow-light),
-      fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-2)
-        var(--color-shadow-light),
-      fun.convert-px(3) fun.convert-px(4) fun.convert-px(5) fun.convert-px(-4)
-        var(--color-shadow-light),
-      fun.convert-px(7) fun.convert-px(10) fun.convert-px(12) fun.convert-px(-3)
-        var(--color-shadow-light);
-    transform: scale(1.05);
-  }
-
-  &:focus {
-    .title {
-      text-decoration: underline solid var(--color-primary) 0.3ex;
-    }
-  }
-
-  &:active {
-    box-shadow: 0 0 0 0 var(--color-shadow);
-    transform: scale(0.95);
-
-    .title {
-      text-decoration: none;
-    }
-  }
-}
-
-.techno {
-  padding: 0 var(--spacing-2xs);
-  border: fun.convert-px(1) solid var(--color-primary-darker);
-}
diff --git a/src/components/ProjectPreview/ProjectPreview.tsx b/src/components/ProjectPreview/ProjectPreview.tsx
deleted file mode 100644
index 1e1ced2..0000000
--- a/src/components/ProjectPreview/ProjectPreview.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import { Project } from '@ts/types/app';
-import { slugify } from '@utils/helpers/slugify';
-import Image from 'next/image';
-import Link from 'next/link';
-import { useIntl } from 'react-intl';
-import styles from './ProjectPreview.module.scss';
-
-const ProjectPreview = ({ project }: { project: Project }) => {
-  const { id, meta, tagline, title } = project;
-  const intl = useIntl();
-
-  return (
-    <Link href={`/projet/${project.slug}`}>
-      <a className={styles.link}>
-        <article className={styles.article}>
-          <header>
-            {meta.hasCover && (
-              <div className={styles.cover}>
-                <Image
-                  src={`/projects/${id}.jpg`}
-                  layout="fill"
-                  objectFit="contain"
-                  objectPosition="center"
-                  alt={intl.formatMessage(
-                    {
-                      defaultMessage: '{title} picture',
-                      description: 'ProjectPreview: cover alt text',
-                      id: '2pykor',
-                    },
-                    { title }
-                  )}
-                />
-              </div>
-            )}
-            <h2 className={styles.title}>{title}</h2>
-          </header>
-          {tagline && (
-            <div
-              className={styles.body}
-              dangerouslySetInnerHTML={{ __html: tagline }}
-            ></div>
-          )}
-          <footer className={styles.footer}>
-            <dl className={styles.meta}>
-              {meta.technologies && (
-                <div className={styles.meta__item}>
-                  <dt className="screen-reader-text">
-                    {intl.formatMessage(
-                      {
-                        defaultMessage:
-                          '{count, plural, =0 {Technologies:} one {Technology:} other {Technologies:}}',
-                        description: 'ProjectPreview: technologies list label',
-                        id: 'okFrAO',
-                      },
-                      { count: meta.technologies.length }
-                    )}
-                  </dt>
-                  {meta.technologies.map((techno) => (
-                    <dd key={slugify(techno)} className={styles.techno}>
-                      {techno}
-                    </dd>
-                  ))}
-                </div>
-              )}
-            </dl>
-          </footer>
-        </article>
-      </a>
-    </Link>
-  );
-};
-
-export default ProjectPreview;
diff --git a/src/components/ProjectSummary/ProjectSummary.module.scss b/src/components/ProjectSummary/ProjectSummary.module.scss
deleted file mode 100644
index cf1e77f..0000000
--- a/src/components/ProjectSummary/ProjectSummary.module.scss
+++ /dev/null
@@ -1,73 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.wrapper {
-  margin-bottom: var(--spacing-md);
-  padding: var(--spacing-sm) var(--spacing-md) var(--spacing-md);
-  border: fun.convert-px(1) solid var(--color-border);
-}
-
-.cover {
-  height: fun.convert-px(150);
-  position: relative;
-}
-
-.info {
-  display: grid;
-  grid-template-columns: repeat(auto-fill, minmax(20ch, 1fr));
-  align-items: start;
-  justify-content: left;
-  column-gap: var(--spacing-md);
-  margin: var(--spacing-md) 0 0;
-}
-
-.inline-data {
-  display: inline-block;
-  margin-top: fun.convert-px(3);
-
-  &:not(:last-of-type) {
-    margin-right: var(--spacing-xs);
-  }
-}
-
-.techno {
-  padding: 0 var(--spacing-2xs);
-  border: fun.convert-px(1) solid var(--color-primary-darker);
-}
-
-.repo {
-  display: block;
-  width: 3em;
-  height: 3em;
-  background: none;
-  box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1)
-      var(--color-shadow),
-    fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-1)
-      var(--color-shadow),
-    fun.convert-px(3) fun.convert-px(4) fun.convert-px(4) fun.convert-px(-3)
-      var(--color-shadow),
-    0 0 0 0 var(--color-shadow);
-  transition: all 0.3s linear 0s;
-
-  &:hover,
-  &:focus {
-    box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1)
-        var(--color-shadow),
-      fun.convert-px(1) fun.convert-px(1) fun.convert-px(2) fun.convert-px(-1)
-        var(--color-shadow-light),
-      fun.convert-px(3) fun.convert-px(3) fun.convert-px(4) fun.convert-px(-4)
-        var(--color-shadow-light),
-      fun.convert-px(6) fun.convert-px(6) fun.convert-px(10) fun.convert-px(-3)
-        var(--color-shadow);
-    transform: scale(1.15);
-  }
-
-  &:focus {
-    outline: var(--color-primary) dashed fun.convert-px(2);
-  }
-
-  &:active {
-    box-shadow: 0 0 0 0 var(--color-shadow);
-    outline: none;
-    transform: scale(0.9);
-  }
-}
diff --git a/src/components/ProjectSummary/ProjectSummary.tsx b/src/components/ProjectSummary/ProjectSummary.tsx
deleted file mode 100644
index 79e783e..0000000
--- a/src/components/ProjectSummary/ProjectSummary.tsx
+++ /dev/null
@@ -1,178 +0,0 @@
-import GithubIcon from '@assets/images/social-media/github.svg';
-import GitlabIcon from '@assets/images/social-media/gitlab.svg';
-import { ProjectMeta } from '@ts/types/app';
-import { settings } from '@utils/config';
-import { getFormattedDate } from '@utils/helpers/format';
-import { slugify } from '@utils/helpers/slugify';
-import useGithubApi from '@utils/hooks/useGithubApi';
-import Image from 'next/image';
-import { useRouter } from 'next/router';
-import { useIntl } from 'react-intl';
-import styles from './ProjectSummary.module.scss';
-
-const ProjectSummary = ({
-  id,
-  meta,
-}: {
-  id: string;
-  title: string;
-  meta: ProjectMeta;
-}) => {
-  const { hasCover, license, repos, technologies } = meta;
-  const intl = useIntl();
-  const router = useRouter();
-  const locale = router.locale ? router.locale : settings.locales.defaultLocale;
-  const { data } = useGithubApi(repos?.github ? repos.github : '');
-
-  return (
-    <div className={styles.wrapper}>
-      {hasCover && (
-        <div className={styles.cover}>
-          <Image
-            src={`/projects/${id}.jpg`}
-            alt={intl.formatMessage({
-              defaultMessage: '{title} preview',
-              description: 'ProjectSummary: cover alt text',
-              id: 'mh7tGg',
-            })}
-            layout="fill"
-            objectFit="contain"
-          />
-        </div>
-      )}
-      <dl className={styles.info}>
-        {data && (
-          <div className={styles.info__item}>
-            <dt>
-              {intl.formatMessage({
-                defaultMessage: 'Created on:',
-                description: 'ProjectSummary: creation date label',
-                id: 'CWi0go',
-              })}
-            </dt>
-            <dd>
-              <time dateTime={data.created_at}>
-                {getFormattedDate(data.created_at, locale)}
-              </time>
-            </dd>
-          </div>
-        )}
-        {data && (
-          <div className={styles.info__item}>
-            <dt>
-              {intl.formatMessage({
-                defaultMessage: 'Last updated on:',
-                description: 'ProjectSummary: update date label',
-                id: 'vJ+QDV',
-              })}
-            </dt>
-            <dd>
-              <time dateTime={data.updated_at}>
-                {getFormattedDate(data.updated_at, locale)}
-              </time>
-            </dd>
-          </div>
-        )}
-        <div className={styles.info__item}>
-          <dt>
-            {intl.formatMessage({
-              defaultMessage: 'License:',
-              description: 'ProjectSummary: license label',
-              id: 'hKagVG',
-            })}
-          </dt>
-          <dd>{license}</dd>
-        </div>
-        {technologies && (
-          <div className={styles.info__item}>
-            <dt>
-              {intl.formatMessage(
-                {
-                  defaultMessage:
-                    '{count, plural, =0 {Technologies:} one {Technology:} other {Technologies:}}',
-                  description: 'ProjectSummary: technologies list label',
-                  id: 'enwhNm',
-                },
-                { count: technologies.length }
-              )}
-            </dt>
-            {technologies.map((techno) => (
-              <dd
-                key={slugify(techno)}
-                className={`${styles.techno} ${styles['inline-data']}`}
-              >
-                {techno}
-              </dd>
-            ))}
-          </div>
-        )}
-        {repos && (
-          <div className={styles.info__item}>
-            <dt>
-              {intl.formatMessage(
-                {
-                  defaultMessage:
-                    '{count, plural, =0 {Repositories:} one {Repository:} other {Repositories:}}',
-                  description: 'ProjectSummary: repositories list label',
-                  id: 'OTTv+m',
-                },
-                { count: Object.keys(repos).length }
-              )}
-            </dt>
-            {repos.github && (
-              <dd className={styles['inline-data']}>
-                <a
-                  href={`https://github.com/${repos.github}`}
-                  className={styles.repo}
-                >
-                  <GithubIcon />
-                  <span className="screen-reader-text">Github</span>
-                </a>
-              </dd>
-            )}
-            {repos.gitlab && (
-              <dd className={styles['inline-data']}>
-                <a
-                  href={`https://gitlab.com/${repos.gitlab}`}
-                  className={styles.repo}
-                >
-                  <GitlabIcon />
-                  <span className="screen-reader-text">Gitlab</span>
-                </a>
-              </dd>
-            )}
-          </div>
-        )}
-        {data && repos && (
-          <div>
-            <dt>
-              {intl.formatMessage({
-                defaultMessage: 'Popularity:',
-                description: 'ProjectSummary: popularity label',
-                id: 'vgMk0q',
-              })}
-            </dt>
-            {repos.github && (
-              <dd>
-                ⭐&nbsp;
-                <a href={`https://github.com/${repos.github}/stargazers`}>
-                  {intl.formatMessage(
-                    {
-                      defaultMessage:
-                        '{starsCount, plural, =0 {0 stars on Github} one {# star on Github} other {# stars on Github}}',
-                      description: 'ProjectSummary: technologies list label',
-                      id: 'aA3hOT',
-                    },
-                    { starsCount: data.stargazers_count }
-                  )}
-                </a>
-              </dd>
-            )}
-          </div>
-        )}
-      </dl>
-    </div>
-  );
-};
-
-export default ProjectSummary;
diff --git a/src/components/ProjectsList/ProjectsList.module.scss b/src/components/ProjectsList/ProjectsList.module.scss
deleted file mode 100644
index fbed08d..0000000
--- a/src/components/ProjectsList/ProjectsList.module.scss
+++ /dev/null
@@ -1,25 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/placeholders";
-
-.list {
-  --items: 4;
-  --items-size: 31ch;
-
-  @extend %reset-list;
-
-  display: grid;
-  grid-template-columns: repeat(
-    auto-fit,
-    min(calc(100vw - (var(--spacing-md) * 2)), var(--items-size))
-  );
-  gap: var(--spacing-sm);
-  place-content: center;
-  width: min(
-    calc(100vw - (var(--spacing-md) * 2)),
-    calc(
-      (var(--items-size) * var(--items)) +
-        (var(--spacing-sm) * (var(--items) - 1))
-    )
-  );
-  margin: var(--spacing-sm) auto 0;
-}
diff --git a/src/components/ProjectsList/ProjectsList.tsx b/src/components/ProjectsList/ProjectsList.tsx
deleted file mode 100644
index 07e6a71..0000000
--- a/src/components/ProjectsList/ProjectsList.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import ProjectPreview from '@components/ProjectPreview/ProjectPreview';
-import { Project } from '@ts/types/app';
-import styles from './ProjectsList.module.scss';
-
-const ProjectsList = ({ projects }: { projects: Project[] }) => {
-  const getProjectItems = () => {
-    return projects.map((project) => {
-      return project.title ? (
-        <li className={styles.item} key={project.id}>
-          <ProjectPreview project={project} />
-        </li>
-      ) : (
-        ''
-      );
-    });
-  };
-
-  return <ul className={styles.list}>{getProjectItems()}</ul>;
-};
-
-export default ProjectsList;
diff --git a/src/components/SearchForm/SearchForm.module.scss b/src/components/SearchForm/SearchForm.module.scss
deleted file mode 100644
index 4debfbb..0000000
--- a/src/components/SearchForm/SearchForm.module.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-.title {
-  margin-bottom: var(--spacing-sm);
-  color: var(--color-primary-dark);
-  font-size: var(--font-size-lg);
-  font-weight: 600;
-}
diff --git a/src/components/SearchForm/SearchForm.tsx b/src/components/SearchForm/SearchForm.tsx
deleted file mode 100644
index f4735af..0000000
--- a/src/components/SearchForm/SearchForm.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import { ButtonSubmit } from '@components/Buttons';
-import { Field, Form } from '@components/FormElements';
-import { SearchIcon } from '@components/Icons';
-import { useRouter } from 'next/router';
-import { FormEvent, useEffect, useRef, useState } from 'react';
-import { useIntl } from 'react-intl';
-import styles from './SearchForm.module.scss';
-
-const SearchForm = ({ isOpened }: { isOpened: boolean }) => {
-  const intl = useIntl();
-  const [query, setQuery] = useState('');
-  const inputRef = useRef<HTMLInputElement>(null);
-  const router = useRouter();
-
-  useEffect(() => {
-    setTimeout(() => {
-      if (isOpened && inputRef.current) {
-        inputRef.current.focus();
-      }
-    }, 400);
-  }, [isOpened]);
-
-  const launchSearch = (e: FormEvent) => {
-    e.preventDefault();
-    router.push({ pathname: '/recherche', query: { s: query } });
-    setQuery('');
-  };
-
-  return (
-    <>
-      <div className={styles.title}>
-        {intl.formatMessage({
-          defaultMessage: 'Search',
-          description: 'SearchForm : form title',
-          id: 'eFMu2E',
-        })}
-      </div>
-      <Form submitHandler={launchSearch} kind="search" id="search">
-        <label htmlFor="search-query" className="screen-reader-text">
-          {intl.formatMessage({
-            defaultMessage: 'Keywords:',
-            description: 'SearchForm: search field label',
-            id: 'YvMPuD',
-          })}
-        </label>
-        <Field
-          ref={inputRef}
-          id="search-query"
-          name="search-query"
-          kind="search"
-          value={query}
-          setValue={setQuery}
-          required={true}
-        />
-        <ButtonSubmit modifier="search">
-          <SearchIcon />
-          <span className="screen-reader-text">
-            {intl.formatMessage({
-              defaultMessage: 'Search',
-              description: 'SearchForm: search button text',
-              id: 'AnaPbu',
-            })}
-          </span>
-        </ButtonSubmit>
-      </Form>
-    </>
-  );
-};
-
-export default SearchForm;
diff --git a/src/components/Settings/AckeeSelect/AckeeSelect.module.scss b/src/components/Settings/AckeeSelect/AckeeSelect.module.scss
deleted file mode 100644
index b145761..0000000
--- a/src/components/Settings/AckeeSelect/AckeeSelect.module.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-.wrapper {
-  display: flex;
-  flex-flow: row wrap;
-  align-items: center;
-  gap: var(--spacing-xs);
-}
diff --git a/src/components/Settings/AckeeSelect/AckeeSelect.tsx b/src/components/Settings/AckeeSelect/AckeeSelect.tsx
deleted file mode 100644
index f711fe2..0000000
--- a/src/components/Settings/AckeeSelect/AckeeSelect.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import { Field, Label } from '@components/FormElements';
-import Tooltip from '@components/Tooltip/Tooltip';
-import { LocalStorage } from '@services/local-storage';
-import { useAckeeTracker } from '@utils/providers/ackee';
-import { useEffect, useState } from 'react';
-import { useIntl } from 'react-intl';
-import styles from './AckeeSelect.module.scss';
-
-const AckeeSelect = () => {
-  const intl = useIntl();
-  const options = [
-    {
-      id: 'partial',
-      name: intl.formatMessage({
-        defaultMessage: 'Partial',
-        description: 'AckeeSelect: partial option name',
-        id: 'e/8Kyj',
-      }),
-      value: 'partial',
-    },
-    {
-      id: 'full',
-      name: intl.formatMessage({
-        defaultMessage: 'Full',
-        description: 'AckeeSelect: full option name',
-        id: 'PzRpPw',
-      }),
-      value: 'full',
-    },
-  ];
-  const [value, setValue] = useState<string>('full');
-  const { setDetailed } = useAckeeTracker();
-
-  useEffect(() => {
-    setDetailed(value === 'full');
-  }, [setDetailed, value]);
-
-  useEffect(() => {
-    const initialState = LocalStorage.get('ackee-tracking');
-    if (initialState) setValue(initialState);
-  }, []);
-
-  useEffect(() => {
-    LocalStorage.set('ackee-tracking', `${value}`);
-  }, [value]);
-
-  const label = (
-    <Label
-      body={intl.formatMessage({
-        defaultMessage: 'Tracking:',
-        description: 'AckeeSelect: select label',
-        id: '2pmylc',
-      })}
-      htmlFor="ackee-settings"
-      kind="settings"
-    />
-  );
-
-  const message = [
-    intl.formatMessage({
-      defaultMessage: 'Partial includes only page url, views and duration.',
-      description: 'AckeeSelect: tooltip message',
-      id: 'skb4W5',
-    }),
-    intl.formatMessage({
-      defaultMessage:
-        'Full includes all information from partial as well as information about referrer, operating system, device, browser, screen size and language.',
-      description: 'AckeeSelect: tooltip message',
-      id: 'Ogccx6',
-    }),
-  ];
-
-  return (
-    <div className={styles.wrapper}>
-      <Field
-        id="ackee-settings"
-        name="ackee-settings"
-        kind="select"
-        label={label}
-        options={options}
-        value={value}
-        setValue={setValue}
-      />
-      <Tooltip
-        message={message}
-        title={intl.formatMessage({
-          defaultMessage: 'Ackee tracking (analytics)',
-          description: 'AckeeSelect: tooltip title',
-          id: 'F1EQX3',
-        })}
-      />
-    </div>
-  );
-};
-
-export default AckeeSelect;
diff --git a/src/components/Settings/PrismThemeToggle/PrismThemeToggle.tsx b/src/components/Settings/PrismThemeToggle/PrismThemeToggle.tsx
deleted file mode 100644
index 20ad267..0000000
--- a/src/components/Settings/PrismThemeToggle/PrismThemeToggle.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import { Toggle } from '@components/FormElements';
-import { MoonIcon, SunIcon } from '@components/Icons';
-import Spinner from '@components/Spinner/Spinner';
-import { usePrismTheme } from '@utils/providers/prism-theme';
-import { useEffect, useState } from 'react';
-import { useIntl } from 'react-intl';
-
-const PrismThemeToggle = () => {
-  const intl = useIntl();
-  const [isMounted, setIsMounted] = useState<boolean>(false);
-
-  useEffect(() => {
-    setIsMounted(true);
-  }, []);
-
-  const { theme, setTheme, resolvedTheme } = usePrismTheme();
-  const [isDarkTheme, setIsDarkTheme] = useState<boolean>(theme === 'dark');
-
-  useEffect(() => {
-    if (theme === 'system') {
-      setIsDarkTheme(resolvedTheme === 'dark');
-    } else {
-      setIsDarkTheme(theme === 'dark');
-    }
-  }, [theme, resolvedTheme]);
-
-  const updateTheme = () => {
-    isDarkTheme ? setTheme('light') : setTheme('dark');
-    setIsDarkTheme(!isDarkTheme);
-  };
-
-  if (!isMounted) return <Spinner />;
-
-  return (
-    <Toggle
-      id="prism-theme"
-      label={intl.formatMessage({
-        defaultMessage: 'Code blocks:',
-        description: 'PrismThemeToggle: toggle label',
-        id: 'w0UfY0',
-      })}
-      leftChoice={<SunIcon />}
-      rightChoice={<MoonIcon />}
-      value={isDarkTheme}
-      changeHandler={updateTheme}
-    />
-  );
-};
-
-export default PrismThemeToggle;
diff --git a/src/components/Settings/ReduceMotion/ReduceMotion.tsx b/src/components/Settings/ReduceMotion/ReduceMotion.tsx
deleted file mode 100644
index 00562cd..0000000
--- a/src/components/Settings/ReduceMotion/ReduceMotion.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import { Toggle } from '@components/FormElements';
-import { LocalStorage } from '@services/local-storage';
-import { useEffect, useState } from 'react';
-import { useIntl } from 'react-intl';
-
-const ReduceMotion = () => {
-  const intl = useIntl();
-  const [isDeactivated, setIsDeactivated] = useState<boolean>(false);
-
-  useEffect(() => {
-    const initialState = LocalStorage.get('reduced-motion');
-    if (initialState) setIsDeactivated(initialState === 'true' ? true : false);
-  }, []);
-
-  useEffect(() => {
-    document.documentElement.dataset.reducedMotion = `${isDeactivated}`;
-    LocalStorage.set('reduced-motion', `${isDeactivated}`);
-  }, [isDeactivated]);
-
-  const updateState = () => {
-    setIsDeactivated(!isDeactivated);
-  };
-
-  return (
-    <Toggle
-      id="reduced-motion"
-      label={intl.formatMessage({
-        defaultMessage: 'Animations:',
-        description: 'ReduceMotion: toggle label',
-        id: 'X3PDXO',
-      })}
-      leftChoice={intl.formatMessage({
-        defaultMessage: 'On',
-        description: 'ReduceMotion: toggle on label',
-        id: 'qPU/Qn',
-      })}
-      rightChoice={intl.formatMessage({
-        defaultMessage: 'Off',
-        description: 'ReduceMotion: toggle off label',
-        id: 'w1nIrj',
-      })}
-      value={isDeactivated}
-      changeHandler={updateState}
-    />
-  );
-};
-
-export default ReduceMotion;
diff --git a/src/components/Settings/Settings.module.scss b/src/components/Settings/Settings.module.scss
deleted file mode 100644
index fe6b17b..0000000
--- a/src/components/Settings/Settings.module.scss
+++ /dev/null
@@ -1,17 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.title {
-  --icon-size: #{fun.convert-px(30)};
-
-  display: flex;
-  flex-flow: row nowrap;
-  gap: var(--spacing-2xs);
-  margin-bottom: var(--spacing-md);
-  color: var(--color-primary-dark);
-  font-size: var(--font-size-lg);
-  font-weight: 600;
-
-  svg {
-    margin: 0;
-  }
-}
diff --git a/src/components/Settings/Settings.tsx b/src/components/Settings/Settings.tsx
deleted file mode 100644
index fec4c45..0000000
--- a/src/components/Settings/Settings.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { CogIcon } from '@components/Icons';
-import ThemeToggle from '@components/Settings/ThemeToggle/ThemeToggle';
-import { useIntl } from 'react-intl';
-import AckeeSelect from './AckeeSelect/AckeeSelect';
-import PrismThemeToggle from './PrismThemeToggle/PrismThemeToggle';
-import ReduceMotion from './ReduceMotion/ReduceMotion';
-import styles from './Settings.module.scss';
-
-const Settings = () => {
-  const intl = useIntl();
-
-  return (
-    <>
-      <div className={styles.title}>
-        <CogIcon />{' '}
-        {intl.formatMessage({
-          defaultMessage: 'Settings',
-          description: 'Settings: modal title',
-          id: 'bHEmkY',
-        })}
-      </div>
-      <ThemeToggle />
-      <ReduceMotion />
-      <PrismThemeToggle />
-      <AckeeSelect />
-    </>
-  );
-};
-
-export default Settings;
diff --git a/src/components/Settings/ThemeToggle/ThemeToggle.tsx b/src/components/Settings/ThemeToggle/ThemeToggle.tsx
deleted file mode 100644
index ec2cee1..0000000
--- a/src/components/Settings/ThemeToggle/ThemeToggle.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Toggle } from '@components/FormElements';
-import { MoonIcon, SunIcon } from '@components/Icons';
-import Spinner from '@components/Spinner/Spinner';
-import { useTheme } from 'next-themes';
-import { useEffect, useState } from 'react';
-import { useIntl } from 'react-intl';
-
-const ThemeToggle = () => {
-  const intl = useIntl();
-  const [isMounted, setIsMounted] = useState<boolean>(false);
-  const { resolvedTheme, setTheme } = useTheme();
-
-  useEffect(() => {
-    setIsMounted(true);
-  }, []);
-
-  if (!isMounted) return <Spinner />;
-
-  const isDarkTheme = resolvedTheme === 'dark';
-
-  const updateTheme = () => {
-    setTheme(isDarkTheme ? 'light' : 'dark');
-  };
-
-  return (
-    <Toggle
-      id="dark-theme"
-      label={intl.formatMessage({
-        defaultMessage: 'Theme:',
-        description: 'ThemeToggle: toggle label',
-        id: 'O9XLDc',
-      })}
-      leftChoice={<SunIcon />}
-      rightChoice={<MoonIcon />}
-      value={isDarkTheme}
-      changeHandler={updateTheme}
-    />
-  );
-};
-
-export default ThemeToggle;
diff --git a/src/components/Sidebar/Sidebar.module.scss b/src/components/Sidebar/Sidebar.module.scss
deleted file mode 100644
index fb6230d..0000000
--- a/src/components/Sidebar/Sidebar.module.scss
+++ /dev/null
@@ -1,43 +0,0 @@
-@use "@styles/abstracts/mixins" as mix;
-
-.wrapper {
-  grid-column: 2;
-
-  &--left {
-    margin: var(--spacing-md) 0;
-  }
-
-  &--right {
-    margin: var(--spacing-md) 0 0;
-  }
-
-  @include mix.media("screen") {
-    @include mix.dimensions("md") {
-      align-self: stretch;
-      margin: 0 var(--spacing-xs) var(--spacing-md);
-
-      &--right {
-        grid-row: 2 / 4;
-        grid-column: 3;
-      }
-    }
-
-    @include mix.dimensions("lg") {
-      &--left {
-        grid-row: 2 / 4;
-        grid-column: 1;
-      }
-    }
-  }
-}
-
-.body {
-  @include mix.media("screen") {
-    @include mix.dimensions("md") {
-      align-self: flex-start;
-      width: 100%;
-      position: sticky;
-      top: var(--spacing-xs);
-    }
-  }
-}
diff --git a/src/components/Sidebar/Sidebar.tsx b/src/components/Sidebar/Sidebar.tsx
deleted file mode 100644
index 9e2079d..0000000
--- a/src/components/Sidebar/Sidebar.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import { Children, cloneElement, isValidElement, ReactNode } from 'react';
-import styles from './Sidebar.module.scss';
-
-type SidebarPosition = 'left' | 'right';
-
-const Sidebar = ({
-  children,
-  position,
-  ariaLabel,
-  title,
-}: {
-  children: ReactNode;
-  position: SidebarPosition;
-  ariaLabel?: string;
-  title?: string;
-}) => {
-  const childrenWithProps = Children.map(children, (child) => {
-    if (isValidElement(child)) {
-      return cloneElement(child, { titleLevel: title ? 3 : 2 });
-    }
-    return child;
-  });
-
-  const positionClass = `wrapper--${position}`;
-
-  return (
-    <aside
-      className={`${styles.wrapper} ${styles[positionClass]}`}
-      aria-label={ariaLabel}
-      aria-labelledby={title ? `${position}-sidebar-title` : undefined}
-    >
-      <div className={styles.body}>
-        {title && <h2 id={`${position}-sidebar-title`}>{title}</h2>}
-        {childrenWithProps}
-      </div>
-    </aside>
-  );
-};
-
-export default Sidebar;
diff --git a/src/components/Spinner/Spinner.module.scss b/src/components/Spinner/Spinner.module.scss
deleted file mode 100644
index 8d818a2..0000000
--- a/src/components/Spinner/Spinner.module.scss
+++ /dev/null
@@ -1,48 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.wrapper {
-  display: flex;
-  flex-flow: row wrap;
-  align-items: center;
-  justify-content: center;
-  gap: var(--spacing-2xs);
-  margin: var(--spacing-md) 0;
-}
-
-.ball {
-  width: fun.convert-px(8);
-  height: fun.convert-px(8);
-  background: linear-gradient(
-    to right,
-    var(--color-primary-light) 0%,
-    var(--color-primary-lighter) 100%
-  );
-  border-radius: 50%;
-  animation: spinner 1.4s infinite ease-in-out both;
-
-  &:first-child {
-    animation-delay: -0.32s;
-  }
-
-  &:nth-child(2) {
-    animation-delay: -0.16s;
-  }
-}
-
-.text {
-  margin-left: var(--spacing-xs);
-  color: var(--color-primary-darker);
-  text-align: center;
-}
-
-@keyframes spinner {
-  0%,
-  80%,
-  100% {
-    transform: scale(0);
-  }
-
-  40% {
-    transform: scale(1);
-  }
-}
diff --git a/src/components/Spinner/Spinner.tsx b/src/components/Spinner/Spinner.tsx
deleted file mode 100644
index 9117d90..0000000
--- a/src/components/Spinner/Spinner.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { useIntl } from 'react-intl';
-import styles from './Spinner.module.scss';
-
-const Spinner = ({ message }: { message?: string }) => {
-  const intl = useIntl();
-
-  return (
-    <div className={styles.wrapper}>
-      <div className={styles.ball}></div>
-      <div className={styles.ball}></div>
-      <div className={styles.ball}></div>
-      <div className={styles.text}>
-        {message ||
-          intl.formatMessage({
-            defaultMessage: 'Loading...',
-            description: 'Spinner: loading text',
-            id: 'q9cJQe',
-          })}
-      </div>
-    </div>
-  );
-};
-
-export default Spinner;
diff --git a/src/components/Toolbar/Toolbar.module.scss b/src/components/Toolbar/Toolbar.module.scss
deleted file mode 100644
index debb3b7..0000000
--- a/src/components/Toolbar/Toolbar.module.scss
+++ /dev/null
@@ -1,114 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-
-.wrapper {
-  --btn-size: #{fun.convert-px(60)};
-
-  display: flex;
-  flex-flow: row wrap;
-  align-items: center;
-  justify-content: space-around;
-  width: 100%;
-  height: var(--toolbar-size);
-  position: fixed;
-  bottom: 0;
-  left: 0;
-  z-index: 5;
-  background: var(--color-bg);
-  border-top: fun.convert-px(4) solid;
-  border-image: radial-gradient(
-      ellipse at top,
-      var(--color-primary-lighter) 20%,
-      var(--color-primary) 100%
-    )
-    1;
-  box-shadow: 0 fun.convert-px(-2) fun.convert-px(3) fun.convert-px(-1)
-    var(--color-shadow-dark);
-
-  :global {
-    animation: slide-in-from-bottom 0.8s ease-in-out 0s 1;
-  }
-
-  @include mix.media("screen") {
-    @include mix.dimensions("sm") {
-      --toolbar-size: auto;
-
-      justify-content: flex-end;
-      gap: var(--spacing-sm);
-      width: auto;
-      background: inherit;
-      border: none;
-      box-shadow: none;
-      position: relative;
-      left: unset;
-      margin-right: unset;
-      transform: unset;
-
-      :global {
-        animation: slide-in-from-top 1s ease-in-out 0s 1;
-      }
-    }
-  }
-}
-
-.menu {
-  padding: var(--spacing-md);
-  position: absolute;
-  bottom: 100%;
-  left: 0;
-  right: 0;
-  background: var(--color-bg-secondary);
-  border-top: fun.convert-px(4) solid;
-  border-bottom: fun.convert-px(4) solid;
-  border-image: radial-gradient(
-      ellipse at top,
-      var(--color-primary-lighter) 20%,
-      var(--color-primary) 100%
-    )
-    1;
-  box-shadow: fun.convert-px(2) fun.convert-px(-2) fun.convert-px(3)
-    fun.convert-px(-1) var(--color-shadow-dark);
-  transition: all 0.7s ease-in-out 0s;
-
-  &--closed {
-    transform: translateX(-100%);
-    visibility: hidden;
-  }
-
-  &--opened {
-    transform: translateX(0);
-    visibility: visible;
-  }
-
-  @include mix.media("screen") {
-    @include mix.dimensions("sm") {
-      width: fun.convert-px(500);
-      left: unset;
-      right: unset;
-      top: 120%;
-      bottom: unset;
-      border: fun.convert-px(4) solid;
-      border-image: radial-gradient(
-          ellipse at top,
-          var(--color-primary-lighter) 20%,
-          var(--color-primary) 100%
-        )
-        1;
-      box-shadow: fun.convert-px(2) fun.convert-px(2) fun.convert-px(3)
-        fun.convert-px(1) var(--color-shadow-dark);
-      transform-origin: 50% -200%;
-      transition: all 0.8s ease-in-out 0s;
-
-      &--closed {
-        opacity: 0;
-        transform: perspective(20rem) translate3d(0, 100%, -20rem);
-        visibility: hidden;
-      }
-
-      &--opened {
-        opacity: 1;
-        transform: none;
-      }
-    }
-  }
-}
diff --git a/src/components/Toolbar/Toolbar.tsx b/src/components/Toolbar/Toolbar.tsx
deleted file mode 100644
index 17f9ef9..0000000
--- a/src/components/Toolbar/Toolbar.tsx
+++ /dev/null
@@ -1,162 +0,0 @@
-import { ButtonToolbar } from '@components/Buttons';
-import MainNav from '@components/MainNav/MainNav';
-import Spinner from '@components/Spinner/Spinner';
-import dynamic from 'next/dynamic';
-import { RefObject, useCallback, useEffect, useRef, useState } from 'react';
-import styles from './Toolbar.module.scss';
-
-const DynamicSearchForm = dynamic(
-  () => import('@components/SearchForm/SearchForm'),
-  {
-    loading: () => <Spinner />,
-  }
-);
-
-const DynamicSettings = dynamic(() => import('@components/Settings/Settings'), {
-  loading: () => <Spinner />,
-});
-
-const Toolbar = () => {
-  const [isNavOpened, setIsNavOpened] = useState<boolean>(false);
-  const [isSearchOpened, setIsSearchOpened] = useState<boolean>(false);
-  const [isSettingsOpened, setIsSettingsOpened] = useState<boolean>(false);
-  const mainNavRef = useRef<HTMLDivElement>(null);
-  const searchBtnRef = useRef<HTMLButtonElement>(null);
-  const searchModalRef = useRef<HTMLDivElement>(null);
-  const settingsBtnRef = useRef<HTMLButtonElement>(null);
-  const settingsModalRef = useRef<HTMLDivElement>(null);
-
-  useEffect(() => {
-    if (isNavOpened) {
-      setIsSearchOpened(false);
-      setIsSettingsOpened(false);
-    }
-  }, [isNavOpened]);
-
-  useEffect(() => {
-    if (isSearchOpened) {
-      setIsNavOpened(false);
-      setIsSettingsOpened(false);
-    }
-  }, [isSearchOpened]);
-
-  useEffect(() => {
-    if (isSettingsOpened) {
-      setIsNavOpened(false);
-      setIsSearchOpened(false);
-    }
-  }, [isSettingsOpened]);
-
-  const isClickOutside = (
-    ref: RefObject<HTMLDivElement>,
-    target: EventTarget
-  ) => {
-    return ref.current && !ref.current.contains(target as Node);
-  };
-
-  const isToggleBtn = (ref: RefObject<HTMLDivElement>, target: EventTarget) => {
-    return (
-      ref.current &&
-      ref.current.previousElementSibling &&
-      ref.current.previousElementSibling.contains(target as Node)
-    );
-  };
-
-  const isSearchBtn = useCallback((target: HTMLElement) => {
-    return (
-      target === searchBtnRef.current || searchBtnRef.current?.contains(target)
-    );
-  }, []);
-
-  const isSettingsBtn = useCallback((target: HTMLElement) => {
-    return (
-      target === settingsBtnRef.current ||
-      settingsBtnRef.current?.contains(target)
-    );
-  }, []);
-
-  const handleVisibility = useCallback(
-    (e: MouseEvent | FocusEvent) => {
-      let ref: RefObject<HTMLDivElement> | null = null;
-      if (isNavOpened) ref = mainNavRef;
-      if (isSearchOpened) ref = searchModalRef;
-      if (isSettingsOpened) ref = settingsModalRef;
-
-      if (!ref || !ref.current || !ref.current.id) return;
-      if (!isClickOutside(ref, e.target as Node)) return;
-      if (isToggleBtn(ref, e.target as Node)) return;
-
-      if (
-        ref.current.id === 'main-nav' &&
-        !isSettingsBtn(e.target as HTMLElement) &&
-        !isSearchBtn(e.target as HTMLElement)
-      ) {
-        setIsNavOpened(false);
-      }
-
-      if (
-        ref.current.id === 'search-modal' &&
-        !isSettingsBtn(e.target as HTMLElement)
-      )
-        setIsSearchOpened(false);
-      if (
-        ref.current.id === 'settings-modal' &&
-        !isSearchBtn(e.target as HTMLElement)
-      )
-        setIsSettingsOpened(false);
-    },
-    [isNavOpened, isSearchOpened, isSettingsOpened, isSearchBtn, isSettingsBtn]
-  );
-
-  useEffect(() => {
-    document.addEventListener('mousedown', handleVisibility);
-    document.addEventListener('focusin', handleVisibility);
-
-    return () => {
-      document.removeEventListener('mousedown', handleVisibility);
-      document.removeEventListener('focusin', handleVisibility);
-    };
-  }, [handleVisibility]);
-
-  const searchClasses = `${styles.menu} ${
-    isSearchOpened ? styles['menu--opened'] : styles['menu--closed']
-  }`;
-
-  const settingsClasses = `${styles.menu} ${
-    isSettingsOpened ? styles['menu--opened'] : styles['menu--closed']
-  }`;
-
-  return (
-    <div className={styles.wrapper}>
-      <MainNav
-        ref={mainNavRef}
-        isOpened={isNavOpened}
-        setIsOpened={setIsNavOpened}
-      />
-      <ButtonToolbar
-        ref={searchBtnRef}
-        type="search"
-        isActivated={isSearchOpened}
-        setIsActivated={setIsSearchOpened}
-      />
-      <div id="search-modal" className={searchClasses} ref={searchModalRef}>
-        <DynamicSearchForm isOpened={isSearchOpened} />
-      </div>
-      <ButtonToolbar
-        ref={settingsBtnRef}
-        type="settings"
-        isActivated={isSettingsOpened}
-        setIsActivated={setIsSettingsOpened}
-      />
-      <div
-        id="settings-modal"
-        className={settingsClasses}
-        ref={settingsModalRef}
-      >
-        <DynamicSettings />
-      </div>
-    </div>
-  );
-};
-
-export default Toolbar;
diff --git a/src/components/Tooltip/Tooltip.module.scss b/src/components/Tooltip/Tooltip.module.scss
deleted file mode 100644
index 34fa23d..0000000
--- a/src/components/Tooltip/Tooltip.module.scss
+++ /dev/null
@@ -1,120 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-
-.title {
-  padding: var(--spacing-2xs) var(--spacing-xs);
-  position: absolute;
-  top: calc(var(--spacing-sm) * -1);
-  left: var(--spacing-lg);
-  background: var(--color-bg);
-  border: fun.convert-px(1) solid var(--color-primary-dark);
-  box-shadow: fun.convert-px(1) fun.convert-px(1) 0 0 var(--color-shadow);
-  color: var(--color-primary-darker);
-  font-size: var(--font-size-sm);
-  font-variant: small-caps;
-  font-weight: 500;
-
-  @include mix.media("screen") {
-    @include mix.dimensions(null, "2xs", "height") {
-      top: 0;
-    }
-
-    @include mix.dimensions("md") {
-      left: var(--spacing-md);
-    }
-  }
-
-  &::before {
-    content: "?";
-    padding: var(--spacing-2xs);
-    position: absolute;
-    top: fun.convert-px(-1);
-    bottom: fun.convert-px(-1);
-    right: 100%;
-    background: var(--color-primary-dark);
-    border: fun.convert-px(1) solid var(--color-primary-dark);
-    box-shadow: fun.convert-px(1) fun.convert-px(1) 0 0 var(--color-shadow);
-    color: var(--color-fg-inverted);
-    font-weight: 600;
-  }
-}
-
-.message {
-  transition: all 0.5s ease-in-out 0;
-}
-
-.wrapper {
-  padding: 9% 6% var(--spacing-sm) 6%;
-  position: absolute;
-  bottom: 30%;
-  left: fun.convert-px(15);
-  right: fun.convert-px(15);
-  background: var(--color-bg);
-  border: fun.convert-px(2) solid var(--color-primary-dark);
-  border-radius: fun.convert-px(3);
-  box-shadow: fun.convert-px(1) fun.convert-px(1) 0 0 var(--color-shadow),
-    fun.convert-px(2) fun.convert-px(2) fun.convert-px(1) fun.convert-px(1)
-      var(--color-shadow-light);
-  transform-origin: bottom;
-
-  @include mix.media("screen") {
-    @include mix.dimensions(null, "2xs", "height") {
-      overflow-y: auto;
-      top: 18%;
-    }
-
-    @include mix.dimensions("sm") {
-      bottom: unset;
-      left: fun.convert-px(15);
-      right: fun.convert-px(15);
-      top: 100%;
-      transform-origin: top;
-    }
-  }
-
-  ul,
-  p {
-    margin: 0;
-    padding: 0;
-  }
-}
-
-.hidden {
-  visibility: hidden;
-  opacity: 0;
-  transition: all 0.5s ease-in-out 0s, opacity 0.3s ease-in-out 0.2s;
-  transform: scaleY(0);
-
-  .message,
-  .title {
-    opacity: 0;
-  }
-
-  .message {
-    transition: all 0.3s ease-in-out 0s;
-  }
-
-  .title {
-    transition: all 0.2s ease-in-out 0.2s;
-  }
-}
-
-.visible {
-  visibility: visible;
-  opacity: 1;
-  transform: scaleY(1);
-  transition: all 0.8s ease-in-out 0s, opacity 0.7s ease-in-out 0.2s;
-
-  .message,
-  .title {
-    opacity: 1;
-  }
-
-  .message {
-    transition: all 0.5s ease-in-out 0.2s;
-  }
-
-  .title {
-    transition: all 0.4s ease-in-out 0s;
-  }
-}
diff --git a/src/components/Tooltip/Tooltip.tsx b/src/components/Tooltip/Tooltip.tsx
deleted file mode 100644
index 56a87ab..0000000
--- a/src/components/Tooltip/Tooltip.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import { ButtonHelp } from '@components/Buttons';
-import { useState } from 'react';
-import { useIntl } from 'react-intl';
-import styles from './Tooltip.module.scss';
-
-const Tooltip = ({
-  message,
-  title,
-}: {
-  message: string | string[];
-  title: string;
-}) => {
-  const intl = useIntl();
-  const [isOpen, setIsOpen] = useState<boolean>(false);
-
-  const getMessageFromArray = (strings: string[]) => {
-    let keyIndex = 0;
-    return (
-      <ul>
-        {strings.map((string) => {
-          keyIndex = keyIndex + 1;
-          return <li key={`message-${keyIndex}`}>{string}</li>;
-        })}
-      </ul>
-    );
-  };
-
-  const buttonTitle = isOpen
-    ? intl.formatMessage({
-        defaultMessage: 'Close help',
-        description: 'Tooltip: button title',
-        id: '9kx83j',
-      })
-    : intl.formatMessage({
-        defaultMessage: 'Show help',
-        description: 'Tooltip: button title',
-        id: 'A5n+C9',
-      });
-
-  const wrapperModifier = isOpen ? styles.visible : styles.hidden;
-
-  return (
-    <div>
-      <ButtonHelp
-        showHelp={isOpen}
-        setShowHelp={setIsOpen}
-        title={buttonTitle}
-      />
-      <div className={`${styles.wrapper} ${wrapperModifier}`}>
-        <div className={styles.title}>{title}</div>
-        <div className={styles.message}>
-          {Array.isArray(message) ? getMessageFromArray(message) : message}
-        </div>
-      </div>
-    </div>
-  );
-};
-
-export default Tooltip;
diff --git a/src/components/WidgetParts/ExpandableWidget/ExpandableWidget.module.scss b/src/components/WidgetParts/ExpandableWidget/ExpandableWidget.module.scss
deleted file mode 100644
index 6a7757d..0000000
--- a/src/components/WidgetParts/ExpandableWidget/ExpandableWidget.module.scss
+++ /dev/null
@@ -1,146 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-
-.title {
-  margin: 0;
-  padding: 0;
-  background: none;
-  font-size: var(--font-size-xl);
-  text-align: left;
-}
-
-.icon {
-  display: flex;
-  flex-flow: row nowrap;
-  align-items: center;
-  justify-content: center;
-  width: fun.convert-px(30);
-  height: fun.convert-px(30);
-  background: var(--color-bg);
-  border: fun.convert-px(1) solid var(--color-primary);
-  border-radius: fun.convert-px(3);
-  color: var(--color-primary);
-  font-weight: 800;
-  transition: all 0.25s ease-in-out 0s;
-
-  &::before,
-  &::after {
-    content: "";
-    background: var(--color-primary);
-    transition: all 0.4s ease-out 0s;
-  }
-
-  &::before {
-    width: 10%;
-    height: 60%;
-    position: relative;
-    left: 30%;
-  }
-
-  &::after {
-    width: 60%;
-    height: 10%;
-    position: relative;
-    left: -5%;
-  }
-}
-
-.body {
-  width: 100%;
-  max-height: 0;
-  margin: 0 0 fun.convert-px(-6); // collapse borders
-  overflow: hidden;
-  visibility: hidden;
-  transition: all 0.6s cubic-bezier(0, 1, 0, 1) 0s, margin 0.2s ease-in-out 0s,
-    border 0.1s ease-in-out 0.3s, visibility 0.1s linear 0.6s;
-
-  &--borders {
-    border: 0 solid transparent;
-  }
-
-  > *:last-child {
-    margin-bottom: 0;
-  }
-
-  @include mix.media("screen") {
-    @include mix.dimensions("md") {
-      font-size: var(--font-size-sm);
-      font-weight: 500;
-    }
-  }
-}
-
-.wrapper {
-  --header-height: #{fun.convert-px(65)};
-
-  display: flex;
-  flex-flow: column;
-
-  &--expanded {
-    .icon::before {
-      height: 0;
-    }
-
-    .body {
-      max-height: 10000px; // needs a fixed value for transition.
-      margin: var(--spacing-sm) 0;
-      overflow: visible;
-      visibility: visible;
-      transition: visibility 0.1s linear 0s, max-height 0.6s linear 0s,
-        margin 0.2s ease-in-out 0s;
-
-      &--borders {
-        border: fun.convert-px(2) solid var(--color-primary-dark);
-      }
-    }
-  }
-}
-
-.wrapper--expanded.wrapper--toc {
-  @include mix.media("screen") {
-    @include mix.dimensions("lg") {
-      max-height: 100vh;
-
-      .body {
-        overflow-y: auto;
-      }
-    }
-  }
-}
-
-.header {
-  display: flex;
-  flex-flow: row nowrap;
-  align-items: center;
-  justify-content: space-between;
-  gap: var(--spacing-md);
-  width: 100%;
-  min-height: var(--header-height);
-  padding: 0;
-  position: sticky;
-  top: 0;
-  z-index: 3;
-  background: var(--color-bg);
-  border: none;
-  border-top: fun.convert-px(2) solid var(--color-primary-dark);
-  border-bottom: fun.convert-px(2) solid var(--color-primary-dark);
-  cursor: pointer;
-
-  &:hover,
-  &:focus {
-    .icon {
-      background: var(--color-primary-light);
-      color: var(--color-fg-inverted);
-      transform: scale(1.2);
-
-      &::before,
-      &::after {
-        background: var(--color-bg);
-      }
-    }
-  }
-
-  > button {
-    padding: 0 var(--spacing-xs);
-  }
-}
diff --git a/src/components/WidgetParts/ExpandableWidget/ExpandableWidget.tsx b/src/components/WidgetParts/ExpandableWidget/ExpandableWidget.tsx
deleted file mode 100644
index 38e57ad..0000000
--- a/src/components/WidgetParts/ExpandableWidget/ExpandableWidget.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-import { TitleLevel } from '@ts/types/app';
-import { ReactNode, useState } from 'react';
-import { useIntl } from 'react-intl';
-import styles from './ExpandableWidget.module.scss';
-
-const ExpandableWidget = ({
-  children,
-  title,
-  titleLevel = 2,
-  expand = false,
-  withBorders = false,
-  kind = 'regular',
-}: {
-  children: ReactNode;
-  title: string;
-  titleLevel?: TitleLevel;
-  expand?: boolean;
-  withBorders?: boolean;
-  kind?: 'regular' | 'toc';
-}) => {
-  const intl = useIntl();
-  const [isExpanded, setIsExpanded] = useState<boolean>(expand);
-
-  const handleExpanse = () => setIsExpanded((prev) => !prev);
-
-  const TitleTag = `h${titleLevel}` as keyof JSX.IntrinsicElements;
-
-  const wrapperKindClass = styles[`wrapper--${kind}`];
-  const wrapperClasses = `${styles.wrapper} ${
-    isExpanded ? styles['wrapper--expanded'] : ''
-  } ${wrapperKindClass}`;
-
-  const bodyClasses = `${styles.body} ${
-    withBorders ? styles['body--borders'] : ''
-  }`;
-
-  return (
-    <div className={wrapperClasses}>
-      <button type="button" className={styles.header} onClick={handleExpanse}>
-        <span className="screen-reader-text">
-          {isExpanded
-            ? intl.formatMessage({
-                defaultMessage: 'Collapse',
-                description: 'ExpandableWidget: collapse text',
-                id: 'WRkY1/',
-              })
-            : intl.formatMessage({
-                defaultMessage: 'Expand',
-                description: 'ExpandableWidget: expand text',
-                id: 'hV0qHp',
-              })}
-        </span>
-        <TitleTag className={styles.title}>{title}</TitleTag>
-        <span className={styles.icon} aria-hidden={true}></span>
-      </button>
-      <div className={bodyClasses}>{children}</div>
-    </div>
-  );
-};
-
-export default ExpandableWidget;
diff --git a/src/components/WidgetParts/List/List.module.scss b/src/components/WidgetParts/List/List.module.scss
deleted file mode 100644
index 958f792..0000000
--- a/src/components/WidgetParts/List/List.module.scss
+++ /dev/null
@@ -1,49 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-
-.list {
-  margin: 0;
-  padding: 0;
-  list-style-type: none;
-
-  .list {
-    border: none;
-    border-top: fun.convert-px(1) solid var(--color-primary-dark);
-  }
-
-  li {
-    margin: 0;
-
-    &:not(:last-of-type) {
-      border-bottom: fun.convert-px(1) solid var(--color-primary-dark);
-    }
-  }
-
-  a {
-    display: flex;
-    flex-flow: row nowrap;
-    width: 100%;
-    padding: var(--spacing-2xs) var(--spacing-xs);
-    background: none;
-    text-decoration: underline solid transparent 0;
-    transition: all 0.2s ease-in-out 0s, font-weight 0s,
-      text-decoration-color 0s;
-
-    &:hover,
-    &:focus {
-      background: var(--color-bg-secondary);
-      font-weight: 600;
-    }
-
-    &:focus {
-      color: var(--color-primary);
-      text-decoration-color: var(--color-primary-light);
-      text-decoration-thickness: 0.25ex;
-    }
-
-    &:active {
-      background: var(--color-bg-tertiary);
-      text-decoration-color: transparent;
-      text-decoration-thickness: 0;
-    }
-  }
-}
diff --git a/src/components/WidgetParts/List/List.tsx b/src/components/WidgetParts/List/List.tsx
deleted file mode 100644
index 317c4d1..0000000
--- a/src/components/WidgetParts/List/List.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import styles from './List.module.scss';
-
-const List = ({ items }: { items: Array<any> }) => {
-  return <ul className={styles.list}>{items}</ul>;
-};
-
-export default List;
diff --git a/src/components/WidgetParts/OrderedList/OrderedList.module.scss b/src/components/WidgetParts/OrderedList/OrderedList.module.scss
deleted file mode 100644
index a286932..0000000
--- a/src/components/WidgetParts/OrderedList/OrderedList.module.scss
+++ /dev/null
@@ -1,66 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/placeholders";
-
-.list {
-  @extend %reset-ordered-list;
-  counter-reset: link;
-
-  .list {
-    border-top: fun.convert-px(1) solid var(--color-primary-dark);
-  }
-
-  a {
-    display: flex;
-    flex-flow: row nowrap;
-    width: 100%;
-    padding: var(--spacing-2xs) var(--spacing-xs);
-    background: none;
-    text-decoration: underline solid transparent 0;
-    transition: all 0.16s ease-in-out 0s, text-decoration-color 0s;
-    counter-increment: link;
-
-    &:hover,
-    &:focus {
-      background: var(--color-bg-secondary);
-    }
-
-    &:focus {
-      color: var(--color-primary);
-      text-decoration-color: var(--color-primary-light);
-      text-decoration-thickness: 0.25ex;
-    }
-
-    &:active {
-      background: var(--color-bg-tertiary);
-      text-decoration-color: transparent;
-      text-decoration-thickness: 0;
-    }
-
-    &::before {
-      content: counters(link, ".") ". ";
-      color: var(--color-secondary);
-      padding-right: var(--spacing-2xs);
-    }
-  }
-
-  li {
-    width: 100%;
-    margin: 0;
-
-    &:not(:last-of-type) {
-      border-bottom: fun.convert-px(1) solid var(--color-primary-dark);
-    }
-
-    &::before {
-      display: none;
-    }
-  }
-
-  li li a::before {
-    padding-left: var(--spacing-sm);
-  }
-
-  li li li a::before {
-    padding-left: var(--spacing-lg);
-  }
-}
diff --git a/src/components/WidgetParts/OrderedList/OrderedList.tsx b/src/components/WidgetParts/OrderedList/OrderedList.tsx
deleted file mode 100644
index a12ec06..0000000
--- a/src/components/WidgetParts/OrderedList/OrderedList.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import styles from './OrderedList.module.scss';
-
-const OrderedList = ({ items }: { items: Array<any> }) => {
-  return <ol className={styles.list}>{items}</ol>;
-};
-
-export default OrderedList;
diff --git a/src/components/WidgetParts/index.tsx b/src/components/WidgetParts/index.tsx
deleted file mode 100644
index 59df3bd..0000000
--- a/src/components/WidgetParts/index.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import ExpandableWidget from './ExpandableWidget/ExpandableWidget';
-import List from './List/List';
-import OrderedList from './OrderedList/OrderedList';
-
-export { ExpandableWidget, List, OrderedList };
diff --git a/src/components/Widgets/CVPreview/CVPreview.module.scss b/src/components/Widgets/CVPreview/CVPreview.module.scss
deleted file mode 100644
index 6ddd696..0000000
--- a/src/components/Widgets/CVPreview/CVPreview.module.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-.preview {
-  position: relative;
-  width: 100%;
-  height: 20rem;
-  margin-bottom: var(--spacing-sm);
-}
diff --git a/src/components/Widgets/CVPreview/CVPreview.tsx b/src/components/Widgets/CVPreview/CVPreview.tsx
deleted file mode 100644
index cf6a8fa..0000000
--- a/src/components/Widgets/CVPreview/CVPreview.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import { ExpandableWidget } from '@components/WidgetParts';
-import Image from 'next/image';
-import Link from 'next/link';
-import { FormattedMessage } from 'react-intl';
-import styles from './CVPreview.module.scss';
-
-const CVPreview = ({
-  title,
-  imgSrc,
-  pdf,
-}: {
-  title: string;
-  imgSrc: string;
-  pdf: string;
-}) => {
-  return (
-    <ExpandableWidget title={title} expand={true}>
-      <div className={styles.preview}>
-        <Image
-          src={imgSrc}
-          layout="fill"
-          objectFit="contain"
-          objectPosition="left"
-          alt="CV Armand Philippot"
-        />
-      </div>
-      <p>
-        <FormattedMessage
-          defaultMessage="Download <link>CV in PDF</link>"
-          description="CVPreview: download as PDF link"
-          id="xC3Khf"
-          values={{
-            link: (chunks: string) => (
-              <Link href={pdf}>
-                <a>{chunks}</a>
-              </Link>
-            ),
-          }}
-        />
-      </p>
-    </ExpandableWidget>
-  );
-};
-
-export default CVPreview;
diff --git a/src/components/Widgets/RecentPosts/RecentPosts.module.scss b/src/components/Widgets/RecentPosts/RecentPosts.module.scss
deleted file mode 100644
index 1b85265..0000000
--- a/src/components/Widgets/RecentPosts/RecentPosts.module.scss
+++ /dev/null
@@ -1,109 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/placeholders";
-
-.list {
-  --items: 3;
-  --items-size: 25ch;
-
-  @extend %reset-list;
-
-  display: grid;
-  grid-template-columns: repeat(
-    auto-fit,
-    min(calc(100vw - (var(--spacing-md) * 2)), var(--items-size))
-  );
-  justify-content: center;
-  gap: var(--spacing-sm);
-  width: min(
-    calc(100vw - (var(--spacing-md) * 2)),
-    calc(
-      (var(--items-size) * var(--items)) +
-        (var(--spacing-sm) * (var(--items) - 1))
-    )
-  );
-  margin-bottom: var(--spacing-md);
-}
-
-.item {
-  text-align: center;
-}
-
-.article {
-  display: flex;
-  flex-flow: column nowrap;
-  height: 100%;
-  padding: 0 0 var(--spacing-md);
-}
-
-.title {
-  flex: 1;
-  margin: var(--spacing-sm) 0;
-  padding: 0 var(--spacing-md);
-  text-decoration: underline solid transparent 0;
-  transition: all 0.3s linear 0s;
-}
-
-.link {
-  display: block;
-  height: 100%;
-  background: var(--color-bg);
-  color: inherit;
-  text-decoration: none;
-  border: fun.convert-px(3) solid var(--color-primary);
-  border-radius: fun.convert-px(5);
-  box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1)
-      var(--color-shadow),
-    fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-2)
-      var(--color-shadow),
-    fun.convert-px(3) fun.convert-px(4) fun.convert-px(5) fun.convert-px(-4)
-      var(--color-shadow);
-  transition: all 0.3s ease-in-out 0s;
-
-  &:hover,
-  &:focus,
-  &:active {
-    color: inherit;
-  }
-
-  &:hover,
-  &:focus {
-    box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1)
-        var(--color-shadow-light),
-      fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-2)
-        var(--color-shadow-light),
-      fun.convert-px(3) fun.convert-px(4) fun.convert-px(5) fun.convert-px(-4)
-        var(--color-shadow-light),
-      fun.convert-px(7) fun.convert-px(10) fun.convert-px(12) fun.convert-px(-3)
-        var(--color-shadow-light);
-    transform: scale(1.05);
-  }
-
-  &:focus {
-    .title {
-      text-decoration: underline solid var(--color-primary) 0.3ex;
-    }
-  }
-
-  &:active {
-    box-shadow: 0 0 0 0 var(--color-shadow);
-    transform: scale(0.95);
-
-    .title {
-      text-decoration: none;
-    }
-  }
-}
-
-.cover {
-  width: 100%;
-  height: clamp(fun.convert-px(100), 20vw, fun.convert-px(150));
-  position: relative;
-  border: fun.convert-px(1) solid var(--color-border);
-}
-
-.meta {
-  display: block;
-  margin: 0;
-  padding: 0 var(--spacing-md);
-  font-size: var(--font-size-sm);
-}
diff --git a/src/components/Widgets/RecentPosts/RecentPosts.tsx b/src/components/Widgets/RecentPosts/RecentPosts.tsx
deleted file mode 100644
index 11d8558..0000000
--- a/src/components/Widgets/RecentPosts/RecentPosts.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import Spinner from '@components/Spinner/Spinner';
-import { getPublishedPosts } from '@services/graphql/queries';
-import { ArticlePreview } from '@ts/types/articles';
-import { PostsList } from '@ts/types/blog';
-import { settings } from '@utils/config';
-import { getFormattedDate } from '@utils/helpers/format';
-import Image from 'next/image';
-import Link from 'next/link';
-import { useRouter } from 'next/router';
-import { useIntl } from 'react-intl';
-import useSWR from 'swr';
-import styles from './RecentPosts.module.scss';
-
-const RecentPosts = ({ posts }: { posts: PostsList }) => {
-  const intl = useIntl();
-  const { data, error } = useSWR<PostsList>(
-    '/recent-posts',
-    () => getPublishedPosts({ first: 3 }),
-    { fallbackData: posts }
-  );
-  const router = useRouter();
-  const locale = router.locale ? router.locale : settings.locales.defaultLocale;
-
-  const getPost = (post: ArticlePreview) => {
-    return (
-      <li key={post.id} className={styles.item}>
-        <Link href={`/article/${post.slug}`}>
-          <a className={styles.link}>
-            <article className={styles.article}>
-              {post.featuredImage &&
-                Object.keys(post.featuredImage).length > 0 && (
-                  <div className={styles.cover}>
-                    <Image
-                      src={post.featuredImage.sourceUrl}
-                      alt={post.featuredImage.altText}
-                      layout="fill"
-                      objectFit="contain"
-                    />
-                  </div>
-                )}
-              <h3 className={styles.title}>{post.title}</h3>
-              <dl className={styles.meta}>
-                <dt>
-                  {intl.formatMessage({
-                    defaultMessage: 'Published on:',
-                    description: 'RecentPosts: publication date label',
-                    id: '1h+N2z',
-                  })}
-                </dt>
-                <dd>
-                  <time dateTime={post.dates.publication}>
-                    {getFormattedDate(post.dates.publication, locale)}
-                  </time>
-                </dd>
-              </dl>
-            </article>
-          </a>
-        </Link>
-      </li>
-    );
-  };
-
-  const getPostsItems = () => {
-    if (error)
-      return intl.formatMessage({
-        defaultMessage: 'Failed to load.',
-        description: 'RecentPosts: failed to load text',
-        id: 'iyEh0R',
-      });
-    if (!data) return <Spinner />;
-
-    return data.posts.map((post) => getPost(post));
-  };
-
-  return <ul className={styles.list}>{getPostsItems()}</ul>;
-};
-
-export default RecentPosts;
diff --git a/src/components/Widgets/RelatedThematics/RelatedThematics.tsx b/src/components/Widgets/RelatedThematics/RelatedThematics.tsx
deleted file mode 100644
index a66de82..0000000
--- a/src/components/Widgets/RelatedThematics/RelatedThematics.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { ExpandableWidget, List } from '@components/WidgetParts';
-import { ThematicPreview } from '@ts/types/taxonomies';
-import Link from 'next/link';
-import { useIntl } from 'react-intl';
-
-const RelatedThematics = ({ thematics }: { thematics: ThematicPreview[] }) => {
-  const intl = useIntl();
-  const sortedThematics = [...thematics].sort((a, b) =>
-    a.title.localeCompare(b.title)
-  );
-
-  const thematicsList = sortedThematics.map((thematic) => {
-    return (
-      <li key={thematic.databaseId}>
-        <Link href={`/thematique/${thematic.slug}`}>
-          <a>{thematic.title}</a>
-        </Link>
-      </li>
-    );
-  });
-
-  return (
-    <ExpandableWidget
-      expand={true}
-      title={intl.formatMessage(
-        {
-          defaultMessage:
-            '{thematicsCount, plural, =0 {Related thematics} one {Related thematic} other {Related thematics}}',
-          description: 'RelatedThematics: widget title',
-          id: 'qXQETZ',
-        },
-        { thematicsCount: thematics.length }
-      )}
-      withBorders={true}
-    >
-      <List items={thematicsList} />
-    </ExpandableWidget>
-  );
-};
-
-export default RelatedThematics;
diff --git a/src/components/Widgets/RelatedTopics/RelatedTopics.tsx b/src/components/Widgets/RelatedTopics/RelatedTopics.tsx
deleted file mode 100644
index 992173d..0000000
--- a/src/components/Widgets/RelatedTopics/RelatedTopics.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { ExpandableWidget, List } from '@components/WidgetParts';
-import { TopicPreview } from '@ts/types/taxonomies';
-import Link from 'next/link';
-import { useIntl } from 'react-intl';
-
-const RelatedTopics = ({ topics }: { topics: TopicPreview[] }) => {
-  const intl = useIntl();
-  const sortedTopics = [...topics].sort((a, b) =>
-    a.title.localeCompare(b.title)
-  );
-
-  const topicsList = sortedTopics.map((topic) => {
-    return (
-      <li key={topic.databaseId}>
-        <Link href={`/sujet/${topic.slug}`}>
-          <a>{topic.title}</a>
-        </Link>
-      </li>
-    );
-  });
-
-  return (
-    <ExpandableWidget
-      expand={true}
-      title={intl.formatMessage(
-        {
-          defaultMessage:
-            '{topicsCount, plural, =0 {Related topics} one {Related topic} other {Related topics}}',
-          description: 'RelatedTopics: widget title',
-          id: 'w/lPUh',
-        },
-        { topicsCount: topicsList.length }
-      )}
-      withBorders={true}
-    >
-      <List items={topicsList} />
-    </ExpandableWidget>
-  );
-};
-
-export default RelatedTopics;
diff --git a/src/components/Widgets/Sharing/Sharing.module.scss b/src/components/Widgets/Sharing/Sharing.module.scss
deleted file mode 100644
index ada3e2f..0000000
--- a/src/components/Widgets/Sharing/Sharing.module.scss
+++ /dev/null
@@ -1,193 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/mixins" as mix;
-@use "@styles/abstracts/placeholders";
-
-.list {
-  @extend %flex-list;
-
-  gap: var(--spacing-sm);
-  padding: var(--spacing-2xs) 0 0 var(--spacing-2xs);
-
-  @include mix.media("screen") {
-    @include mix.dimensions("md") {
-      gap: var(--spacing-xs);
-      width: min-content;
-    }
-  }
-}
-
-.link {
-  display: flex;
-  flex-flow: row nowrap;
-  align-items: center;
-  padding: var(--spacing-2xs) var(--spacing-xs);
-  border-radius: fun.convert-px(3);
-  font-weight: 600;
-  text-decoration: none;
-  transition: all 0.3s ease-in-out 0s;
-
-  &:hover,
-  &:focus {
-    color: hsl(0, 0%, 100%);
-    transform: translateX(#{fun.convert-px(-3)})
-      translateY(#{fun.convert-px(-3)});
-  }
-
-  &:active {
-    color: hsl(0, 0%, 100%);
-    transform: translateX(#{fun.convert-px(2)}) translateY(#{fun.convert-px(2)});
-
-    @include mix.motion("reduce") {
-      transform: none;
-    }
-  }
-
-  &::before {
-    display: block;
-    background-repeat: no-repeat;
-    content: "";
-    filter: drop-shadow(
-      #{fun.convert-px(1)} #{fun.convert-px(1)} #{fun.convert-px(1)} hsl(0, 0%, 0%)
-    );
-    width: fun.convert-px(30);
-    height: fun.convert-px(30);
-  }
-
-  &--diaspora {
-    background: hsl(0, 0%, 13%);
-    box-shadow: #{fun.convert-px(3)} #{fun.convert-px(3)} 0 0 hsl(0, 0%, 3%);
-
-    &:hover,
-    &:focus {
-      box-shadow: #{fun.convert-px(6)} #{fun.convert-px(6)} 0 0 hsl(0, 0%, 3%);
-    }
-
-    &:active {
-      box-shadow: #{fun.convert-px(1)} #{fun.convert-px(1)} 0 0 hsl(0, 0%, 3%);
-    }
-
-    &::before {
-      background-image: url(fun.encode-svg(
-        '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path style="fill:#ffffff;" d="M15.257 21.928l-2.33-3.255c-.622-.87-1.128-1.549-1.155-1.55-.027 0-1.007 1.317-2.317 3.115-1.248 1.713-2.28 3.115-2.292 3.115-.035 0-4.5-3.145-4.51-3.178-.006-.016 1.003-1.497 2.242-3.292 1.239-1.794 2.252-3.29 2.252-3.325 0-.056-.401-.197-3.55-1.247a1604.93 1604.93 0 01-3.593-1.2c-.033-.013.153-.635.79-2.648.46-1.446.845-2.642.857-2.656.013-.015 1.71.528 3.772 1.207 2.062.678 3.766 1.233 3.787 1.233.021 0 .045-.032.053-.07.008-.039.026-1.794.04-3.902.013-2.107.036-3.848.05-3.87.02-.03.599-.038 2.725-.038 1.485 0 2.716.01 2.735.023.023.016.064 1.175.132 3.776.112 4.273.115 4.33.183 4.33.026 0 1.66-.547 3.631-1.216 1.97-.668 3.593-1.204 3.605-1.191.04.045 1.656 5.307 1.636 5.327-.011.01-1.656.574-3.655 1.252-2.75.932-3.638 1.244-3.645 1.284-.006.029.94 1.442 2.143 3.202 1.184 1.733 2.148 3.164 2.143 3.18-.012.036-4.442 3.299-4.48 3.299-.015 0-.577-.767-1.249-1.705z"/></svg>'
-      ));
-    }
-  }
-
-  &--email {
-    background: hsl(0, 0%, 44%);
-    box-shadow: #{fun.convert-px(3)} #{fun.convert-px(3)} 0 0 hsl(0, 0%, 34%);
-
-    &:hover,
-    &:focus {
-      box-shadow: #{fun.convert-px(6)} #{fun.convert-px(6)} 0 0 hsl(0, 0%, 34%);
-    }
-
-    &:active {
-      box-shadow: #{fun.convert-px(1)} #{fun.convert-px(1)} 0 0 hsl(0, 0%, 34%);
-    }
-
-    &::before {
-      background-image: url(fun.encode-svg(
-        '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill:#ffffff;" d="M15.909 12.123L24 17.238V6.792zM0 6.792v10.446l8.091-5.115zM22.5 3.75h-21c-.748 0-1.343.558-1.455 1.276L12 12.904l11.955-7.877c-.112-.718-.706-1.276-1.455-1.276zm-7.965 9.279l-2.123 1.398a.75.75 0 01-.825 0l-2.122-1.4-9.417 5.957c.116.712.707 1.266 1.452 1.266h21c.746 0 1.337-.553 1.452-1.266z"/></svg>'
-      ));
-    }
-  }
-
-  &--facebook {
-    background: hsl(214, 89%, 52%);
-    box-shadow: #{fun.convert-px(3)} #{fun.convert-px(3)} 0 0 hsl(214, 89%, 42%);
-
-    &:hover,
-    &:focus {
-      box-shadow: #{fun.convert-px(6)} #{fun.convert-px(6)} 0 0
-        hsl(214, 89%, 42%);
-    }
-
-    &:active {
-      box-shadow: #{fun.convert-px(1)} #{fun.convert-px(1)} 0 0
-        hsl(214, 89%, 42%);
-    }
-
-    &::before {
-      background-image: url(fun.encode-svg(
-        '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill:#ffffff;" d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>'
-      ));
-    }
-  }
-
-  &--journal-du-hacker {
-    background: hsl(210, 24%, 51%);
-    box-shadow: #{fun.convert-px(3)} #{fun.convert-px(3)} 0 0 hsl(210, 24%, 41%);
-
-    &:hover,
-    &:focus {
-      box-shadow: #{fun.convert-px(6)} #{fun.convert-px(6)} 0 0
-        hsl(210, 24%, 41%);
-    }
-
-    &:active {
-      box-shadow: #{fun.convert-px(1)} #{fun.convert-px(1)} 0 0
-        hsl(210, 24%, 41%);
-    }
-
-    &::before {
-      background-image: url(fun.encode-svg(
-        '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill:#ffffff;" d="M17.822 23.297a6.644 6.644 0 00-.654.032c-1.104.1-2.451-.378-3.244-1.15a3.223 3.223 0 01-.52-.739c-.209-.425-.22-.489-.211-1.178a8.174 8.174 0 01.19-1.585c.243-1.151.155-1.449-.514-1.737-.4-.172-.632-.135-1 .16-.268.215-.28.463-.07 1.532.298 1.526.286 2.238-.05 2.907-.28.56-.443.703-1.287 1.133-1.005.513-1.461.638-2.332.638-.73 0-1.014-.082-1.276-.366-.134-.145-.148-.2-.085-.32.099-.184.329-.3.959-.488.277-.082.604-.236.727-.341.123-.105.329-.265.457-.354.32-.222.562-.761.563-1.254 0-.331-.188-1.034-.45-1.676-.138-.338-.38.085-.38.666 0 .434-.673 1.569-.93 1.569-.048 0-.288.101-.532.225-.43.219-.47.225-1.31.225-.815 0-.889-.011-1.235-.194-.42-.22-.902-.694-1.094-1.073a2.752 2.752 0 00-.227-.377c-.083-.102-.08-.143.018-.293.206-.314.473-.317 1.186-.011.583.25 1.22.215 1.582-.086.168-.139.325-.697.342-1.217.02-.598-.049-.66-.596-.528-.86.206-1.762-.084-2.76-.887-.916-.739-1.362-.845-2.241-.538-.262.092-.51.153-.552.137-.042-.016-.134-.136-.204-.268-.118-.218-.12-.252-.02-.403.156-.24.714-.573 1.185-.708.297-.086.588-.11 1.076-.09.655.026.687.035 1.567.458.54.259.99.43 1.127.43.27 0 1.014-.37 1.159-.577.167-.238.124-.34-.322-.776-1.19-1.16-1.943-2.608-2.24-4.31-.124-.702-.14-1.888-.035-2.483.116-.656.677-2.273.915-2.64.385-.59 1.823-1.965 2.585-2.469C9.187.905 11.43.395 13.715.785c2.457.42 4.507 1.61 5.849 3.394 1.062 1.414 1.554 2.859 1.553 4.57 0 1.778-.497 3.238-1.599 4.693a6.207 6.207 0 00-.34.476c0 .013.205.12.456.238.737.345 1.169.844 1.726 1.994.256.527.531 1.031.613 1.12.225.247.614.42 1.099.49.588.085.804.178.9.388.109.24-.111.55-.402.563-.11.005-.394.033-.63.062-.887.107-1.851-.251-2.416-.898-.17-.193-.503-.616-.74-.939-.455-.616-.818-.922-1.054-.888-.117.017-.14.066-.127.28.008.142.068.34.133.438.09.137.127.412.161 1.196.05 1.153.147 1.458.55 1.726.306.204.552.198 1.11-.025.581-.233.923-.238 1.159-.018.243.227.2.637-.11 1.026-.33.419-1.338.899-2.001.954-1.194.1-2.371-.602-2.828-1.686-.062-.147-.197-.61-.301-1.03-.12-.486-.221-.762-.28-.762-.109 0-.263.401-.27.705-.003.12-.056.417-.118.657-.328 1.282.307 2.309 1.66 2.684.657.182.808.299.808.623 0 .319-.165.494-.454.481z"/></svg>'
-      ));
-    }
-  }
-
-  &--linkedin {
-    background: hsl(210, 90%, 40%);
-    box-shadow: #{fun.convert-px(3)} #{fun.convert-px(3)} 0 0 hsl(210, 90%, 30%);
-
-    &:hover,
-    &:focus {
-      box-shadow: #{fun.convert-px(6)} #{fun.convert-px(6)} 0 0
-        hsl(210, 90%, 30%);
-    }
-
-    &:active {
-      box-shadow: #{fun.convert-px(1)} #{fun.convert-px(1)} 0 0
-        hsl(210, 90%, 30%);
-    }
-
-    &::before {
-      background-image: url(fun.encode-svg(
-        '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path style="fill:#ffffff;" d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>'
-      ));
-    }
-  }
-
-  &--twitter {
-    background: hsl(203, 89%, 53%);
-    box-shadow: #{fun.convert-px(3)} #{fun.convert-px(3)} 0 0 hsl(203, 89%, 43%);
-
-    &:hover,
-    &:focus {
-      box-shadow: #{fun.convert-px(6)} #{fun.convert-px(6)} 0 0
-        hsl(203, 89%, 43%);
-    }
-
-    &:active {
-      box-shadow: #{fun.convert-px(1)} #{fun.convert-px(1)} 0 0
-        hsl(203, 89%, 43%);
-    }
-
-    &::before {
-      background-image: url(fun.encode-svg(
-        '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path style="fill:#ffffff;" d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/></svg>'
-      ));
-    }
-  }
-}
-
-:global {
-  [data-theme="dark"] {
-    :local {
-      .link {
-        filter: brightness(0.85) contrast(1.1);
-      }
-    }
-  }
-}
diff --git a/src/components/Widgets/Sharing/Sharing.tsx b/src/components/Widgets/Sharing/Sharing.tsx
deleted file mode 100644
index 45fe3ce..0000000
--- a/src/components/Widgets/Sharing/Sharing.tsx
+++ /dev/null
@@ -1,238 +0,0 @@
-import { ExpandableWidget } from '@components/WidgetParts';
-import { useRouter } from 'next/router';
-import { useEffect, useState } from 'react';
-import { useIntl } from 'react-intl';
-import styles from './Sharing.module.scss';
-
-type Parameters = {
-  content: string;
-  image: string;
-  title: string;
-  url: string;
-};
-
-type Website = {
-  id: string;
-  name: string;
-  parameters: Parameters;
-  url: string;
-};
-
-const Sharing = ({ excerpt, title }: { excerpt: string; title: string }) => {
-  const intl = useIntl();
-  const [pageExcerpt, setPageExcerpt] = useState('');
-  const [pageUrl, setPageUrl] = useState('');
-  const [domainName, setDomainName] = useState('');
-  const router = useRouter();
-
-  useEffect(() => {
-    const divEl = document.createElement('div');
-    divEl.innerHTML = excerpt;
-    const cleanExcerpt = divEl.textContent!;
-    setPageExcerpt(cleanExcerpt);
-  }, [excerpt]);
-
-  useEffect(() => {
-    const { protocol, hostname, port } = window.location;
-    const currentPort = port ? `:${port}` : '';
-    const fullUrl = `${protocol}//${hostname}${currentPort}${router.asPath}`;
-
-    setDomainName(hostname);
-    setPageUrl(fullUrl);
-  }, [router.asPath]);
-
-  const getSharingUrl = (website: Website): string => {
-    const { id, parameters, url } = website;
-    let sharingUrl = `${url}?`;
-    let count = 0;
-
-    for (const [key, value] of Object.entries(parameters)) {
-      if (!value) continue;
-
-      sharingUrl += count > 0 ? `&${value}=` : `${value}=`;
-
-      switch (key) {
-        case 'content':
-          if (id === 'email') {
-            const intro = intl.formatMessage({
-              defaultMessage: 'Introduction:',
-              description: 'Sharing: email content prefix',
-              id: 'yfgMcl',
-            });
-            const readMore = intl.formatMessage({
-              defaultMessage: 'Read more here:',
-              description: 'Sharing: content link prefix',
-              id: 'UsQske',
-            });
-            const body = `${intro}\n\n"${pageExcerpt}"\n\n${readMore} ${pageUrl}`;
-            sharingUrl += encodeURI(body);
-          } else {
-            sharingUrl += encodeURI(pageExcerpt);
-          }
-          break;
-        case 'title':
-          const prefix =
-            id === 'email'
-              ? intl.formatMessage(
-                  {
-                    defaultMessage: 'Seen on {domainName}:',
-                    description: 'Sharing: seen on text',
-                    id: 'eUXMG4',
-                  },
-                  { domainName }
-                )
-              : '';
-          sharingUrl += encodeURI(`${prefix} ${title}`);
-          break;
-        case 'url':
-          sharingUrl += encodeURI(pageUrl);
-          break;
-        default:
-          break;
-      }
-
-      count++;
-    }
-
-    return sharingUrl;
-  };
-
-  const websites = [
-    {
-      id: 'diaspora',
-      name: intl.formatMessage({
-        defaultMessage: 'Diaspora',
-        description: 'Sharing: Diaspora',
-        id: 'Dhow1m',
-      }),
-      parameters: {
-        content: '',
-        image: '',
-        title: 'title',
-        url: 'url',
-      },
-      url: 'https://share.diasporafoundation.org/',
-    },
-    {
-      id: 'facebook',
-      name: intl.formatMessage({
-        defaultMessage: 'Facebook',
-        description: 'Sharing: Facebook',
-        id: '7iiaRx',
-      }),
-      parameters: {
-        content: '',
-        image: '',
-        title: '',
-        url: 'u',
-      },
-      url: 'https://www.facebook.com/sharer/sharer.php',
-    },
-    {
-      id: 'linkedin',
-      name: intl.formatMessage({
-        defaultMessage: 'LinkedIn',
-        description: 'Sharing: LinkedIn',
-        id: 'csCQQk',
-      }),
-      parameters: {
-        content: '',
-        image: '',
-        title: '',
-        url: 'url',
-      },
-      url: 'https://www.linkedin.com/sharing/share-offsite/',
-    },
-    {
-      id: 'twitter',
-      name: intl.formatMessage({
-        defaultMessage: 'Twitter',
-        description: 'Sharing: Twitter',
-        id: 'WjVBnY',
-      }),
-      parameters: {
-        content: '',
-        image: '',
-        title: 'text',
-        url: 'url',
-      },
-      url: 'https://twitter.com/intent/tweet',
-    },
-    {
-      id: 'journal-du-hacker',
-      name: intl.formatMessage({
-        defaultMessage: 'Journal du hacker',
-        description: 'Sharing: Journal du hacker',
-        id: 'P0I+Xm',
-      }),
-      parameters: {
-        content: '',
-        image: '',
-        title: 'title',
-        url: 'url',
-      },
-      url: 'https://www.journalduhacker.net/stories/new',
-    },
-    {
-      id: 'email',
-      name: intl.formatMessage({
-        defaultMessage: 'Email',
-        description: 'Sharing: Email',
-        id: 'lKZm9t',
-      }),
-      parameters: {
-        content: 'body',
-        image: '',
-        title: 'subject',
-        url: '',
-      },
-      url: 'mailto:',
-    },
-  ];
-
-  const getItems = () => {
-    return websites.map((website) => {
-      const { id, name } = website;
-      const sharingUrl = getSharingUrl(website);
-      const linkModifier = `link--${id}`;
-
-      return (
-        <li key={id}>
-          <a
-            href={sharingUrl}
-            title={name}
-            className={`${styles.link} ${styles[linkModifier]}`}
-          >
-            <span className="screen-reader-text">
-              {intl.formatMessage(
-                {
-                  defaultMessage: 'Share on {name}',
-                  description: 'Sharing: share on social network text',
-                  id: 'ureXFw',
-                },
-                { name }
-              )}
-            </span>
-          </a>
-        </li>
-      );
-    });
-  };
-
-  return (
-    <ExpandableWidget
-      title={intl.formatMessage({
-        defaultMessage: 'Share',
-        description: 'Sharing: widget title',
-        id: 'q3U6uI',
-      })}
-      expand={true}
-    >
-      <ul className={`${styles.list} ${styles['list--sharing']}`}>
-        {getItems()}
-      </ul>
-    </ExpandableWidget>
-  );
-};
-
-export default Sharing;
diff --git a/src/components/Widgets/SocialMedia/SocialMedia.module.scss b/src/components/Widgets/SocialMedia/SocialMedia.module.scss
deleted file mode 100644
index 2ef34bf..0000000
--- a/src/components/Widgets/SocialMedia/SocialMedia.module.scss
+++ /dev/null
@@ -1,59 +0,0 @@
-@use "@styles/abstracts/functions" as fun;
-@use "@styles/abstracts/placeholders";
-
-.list {
-  @extend %flex-list;
-
-  flex: 0 0 100%;
-  gap: var(--spacing-xs);
-  align-items: center;
-  padding: var(--spacing-2xs) 0 0 var(--spacing-2xs);
-}
-
-.link {
-  display: block;
-  width: 3em;
-  height: 3em;
-  background: none;
-  box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1)
-      var(--color-shadow),
-    fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-1)
-      var(--color-shadow),
-    fun.convert-px(3) fun.convert-px(4) fun.convert-px(4) fun.convert-px(-3)
-      var(--color-shadow),
-    0 0 0 0 var(--color-shadow);
-  transition: all 0.3s linear 0s;
-
-  &:hover,
-  &:focus {
-    box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1)
-        var(--color-shadow),
-      fun.convert-px(1) fun.convert-px(1) fun.convert-px(2) fun.convert-px(-1)
-        var(--color-shadow-light),
-      fun.convert-px(3) fun.convert-px(3) fun.convert-px(4) fun.convert-px(-4)
-        var(--color-shadow-light),
-      fun.convert-px(6) fun.convert-px(6) fun.convert-px(10) fun.convert-px(-3)
-        var(--color-shadow);
-    transform: scale(1.15);
-  }
-
-  &:focus {
-    outline: var(--color-primary) dashed fun.convert-px(2);
-  }
-
-  &:active {
-    box-shadow: 0 0 0 0 var(--color-shadow);
-    outline: none;
-    transform: scale(0.9);
-  }
-}
-
-:global {
-  [data-theme="dark"] {
-    :local {
-      .icon {
-        filter: brightness(0.85) contrast(1.1);
-      }
-    }
-  }
-}
diff --git a/src/components/Widgets/SocialMedia/SocialMedia.tsx b/src/components/Widgets/SocialMedia/SocialMedia.tsx
deleted file mode 100644
index decf657..0000000
--- a/src/components/Widgets/SocialMedia/SocialMedia.tsx
+++ /dev/null
@@ -1,113 +0,0 @@
-import GithubIcon from '@assets/images/social-media/github.svg';
-import GitlabIcon from '@assets/images/social-media/gitlab.svg';
-import LinkedInIcon from '@assets/images/social-media/linkedin.svg';
-import TwitterIcon from '@assets/images/social-media/twitter.svg';
-import styles from './SocialMedia.module.scss';
-import { ExpandableWidget } from '@components/WidgetParts';
-import { useIntl } from 'react-intl';
-
-const SocialMedia = ({
-  title,
-  github = false,
-  gitlab = false,
-  linkedin = false,
-  twitter = false,
-}: {
-  title: string;
-  github?: boolean;
-  gitlab?: boolean;
-  linkedin?: boolean;
-  twitter?: boolean;
-}) => {
-  const intl = useIntl();
-
-  const websites = [
-    {
-      id: 'github',
-      name: intl.formatMessage({
-        defaultMessage: 'Github',
-        description: 'SocialMedia: Github',
-        id: 'SWjj4l',
-      }),
-      url: 'https://github.com/ArmandPhilippot',
-    },
-    {
-      id: 'gitlab',
-      name: intl.formatMessage({
-        defaultMessage: 'Gitlab',
-        description: 'SocialMedia: Gitlab',
-        id: 'obmlFh',
-      }),
-      url: 'https://gitlab.com/ArmandPhilippot',
-    },
-    {
-      id: 'linkedin',
-      name: intl.formatMessage({
-        defaultMessage: 'LinkedIn',
-        description: 'SocialMedia: LinkedIn',
-        id: 'VbcHZ4',
-      }),
-      url: 'https://www.linkedin.com/in/armandphilippot',
-    },
-    {
-      id: 'twitter',
-      name: intl.formatMessage({
-        defaultMessage: 'Twitter',
-        description: 'SocialMedia: Twitter',
-        id: 'IPs/Ck',
-      }),
-      url: 'https://twitter.com/ArmandPhilippot',
-    },
-  ];
-
-  const getIcon = (id: string) => {
-    switch (id) {
-      case 'github':
-        return <GithubIcon className={styles.icon} />;
-      case 'gitlab':
-        return <GitlabIcon className={styles.icon} />;
-      case 'linkedin':
-        return <LinkedInIcon className={styles.icon} />;
-      case 'twitter':
-        return <TwitterIcon className={styles.icon} />;
-      default:
-        break;
-    }
-  };
-
-  const shouldDisplayLink = (id: string) => {
-    switch (id) {
-      case 'github':
-        return github;
-      case 'gitlab':
-        return gitlab;
-      case 'linkedin':
-        return linkedin;
-      case 'twitter':
-        return twitter;
-      default:
-        break;
-    }
-  };
-
-  const items = websites.map((website) => {
-    return shouldDisplayLink(website.id) ? (
-      <li key={website.id}>
-        <a href={website.url} className={styles.link}>
-          {getIcon(website.id)}
-          <span className="screen-reader-text">{website.name}</span>
-        </a>
-      </li>
-    ) : (
-      ''
-    );
-  });
-
-  return (
-    <ExpandableWidget title={title} expand={true}>
-      <ul className={styles.list}>{items}</ul>
-    </ExpandableWidget>
-  );
-};
-
-export default SocialMedia;
diff --git a/src/components/Widgets/ThematicsList/ThematicsList.tsx b/src/components/Widgets/ThematicsList/ThematicsList.tsx
deleted file mode 100644
index 51254ee..0000000
--- a/src/components/Widgets/ThematicsList/ThematicsList.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import Spinner from '@components/Spinner/Spinner';
-import { ExpandableWidget, List } from '@components/WidgetParts';
-import { getAllThematics } from '@services/graphql/queries';
-import { TitleLevel } from '@ts/types/app';
-import { ThematicPreview } from '@ts/types/taxonomies';
-import Link from 'next/link';
-import { useRouter } from 'next/router';
-import { useIntl } from 'react-intl';
-import useSWR from 'swr';
-
-const ThematicsList = ({
-  title,
-  titleLevel,
-  initialData,
-}: {
-  title: string;
-  titleLevel?: TitleLevel;
-  initialData?: ThematicPreview[];
-}) => {
-  const intl = useIntl();
-  const router = useRouter();
-  const isThematic = () => router.asPath.includes('/thematique/');
-  const currentThematicSlug = isThematic()
-    ? router.asPath.replace('/thematique/', '')
-    : '';
-
-  const { data, error } = useSWR('/api/thematics', getAllThematics, {
-    fallbackData: initialData,
-  });
-
-  const getList = () => {
-    if (error)
-      return (
-        <ul>
-          {intl.formatMessage({
-            defaultMessage: 'Failed to load.',
-            description: 'ThematicsList: failed to load text',
-            id: 'PxMDzL',
-          })}
-        </ul>
-      );
-    if (!data)
-      return (
-        <ul>
-          <Spinner />
-        </ul>
-      );
-
-    const thematics = data.map((thematic) => {
-      return currentThematicSlug !== thematic.slug ? (
-        <li key={thematic.databaseId}>
-          <Link href={`/thematique/${thematic.slug}`}>
-            <a>{thematic.title}</a>
-          </Link>
-        </li>
-      ) : (
-        ''
-      );
-    });
-
-    return <List items={thematics} />;
-  };
-
-  return (
-    <ExpandableWidget
-      title={title}
-      titleLevel={titleLevel}
-      withBorders={true}
-      expand={true}
-    >
-      {getList()}
-    </ExpandableWidget>
-  );
-};
-
-export default ThematicsList;
diff --git a/src/components/Widgets/ToC/ToC.tsx b/src/components/Widgets/ToC/ToC.tsx
deleted file mode 100644
index 3f759db..0000000
--- a/src/components/Widgets/ToC/ToC.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import { ExpandableWidget, OrderedList } from '@components/WidgetParts';
-import { Heading } from '@ts/types/app';
-import useHeadingsTree from '@utils/hooks/useHeadingsTree';
-import { FormattedMessage, useIntl } from 'react-intl';
-
-const ToC = () => {
-  const intl = useIntl();
-  const headingsTree = useHeadingsTree('article');
-  const title = intl.formatMessage({
-    defaultMessage: 'Table of contents',
-    description: 'ToC: widget title',
-    id: 'Zg4L7U',
-  });
-
-  const getItems = (headings: Heading[]) => {
-    return headings.map((heading) => {
-      return (
-        <li key={heading.id}>
-          <a href={`#${heading.id}`}>
-            <FormattedMessage
-              defaultMessage="<a11y>Jump to </a11y>{title}"
-              description="ToC: link"
-              id="GgIWnN"
-              values={{
-                title: heading.title,
-                a11y: (chunks: string) => (
-                  <span className="screen-reader-text">{chunks}</span>
-                ),
-              }}
-            />
-          </a>
-          {heading.children.length > 0 && (
-            <OrderedList items={getItems(heading.children)} />
-          )}
-        </li>
-      );
-    });
-  };
-
-  return (
-    <ExpandableWidget title={title} kind="toc" expand={true} withBorders={true}>
-      <noscript>
-        {intl.formatMessage({
-          defaultMessage:
-            'Javascript is required to use the table of contents.',
-          description: 'ToC: noscript tag',
-          id: 'RZzx/4',
-        })}
-      </noscript>
-      <OrderedList items={getItems(headingsTree)} />
-    </ExpandableWidget>
-  );
-};
-
-export default ToC;
diff --git a/src/components/Widgets/TopicsList/TopicsList.tsx b/src/components/Widgets/TopicsList/TopicsList.tsx
deleted file mode 100644
index 7bc7d70..0000000
--- a/src/components/Widgets/TopicsList/TopicsList.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import Spinner from '@components/Spinner/Spinner';
-import { ExpandableWidget, List } from '@components/WidgetParts';
-import { getAllTopics } from '@services/graphql/queries';
-import { TitleLevel } from '@ts/types/app';
-import { TopicPreview } from '@ts/types/taxonomies';
-import Link from 'next/link';
-import { useRouter } from 'next/router';
-import { useIntl } from 'react-intl';
-import useSWR from 'swr';
-
-const TopicsList = ({
-  title,
-  titleLevel,
-  initialData,
-}: {
-  title: string;
-  titleLevel?: TitleLevel;
-  initialData?: TopicPreview[];
-}) => {
-  const intl = useIntl();
-  const router = useRouter();
-  const isTopic = () => router.asPath.includes('/sujet/');
-  const currentTopicSlug = isTopic()
-    ? router.asPath.replace('/sujet/', '')
-    : '';
-
-  const { data, error } = useSWR('/api/topics', getAllTopics, {
-    fallbackData: initialData,
-  });
-
-  const getList = () => {
-    if (error)
-      return (
-        <ul>
-          {intl.formatMessage({
-            defaultMessage: 'Failed to load.',
-            description: 'TopicsList: failed to load text',
-            id: '00Pf5p',
-          })}
-        </ul>
-      );
-    if (!data)
-      return (
-        <ul>
-          <Spinner />
-        </ul>
-      );
-
-    const topics = data.map((topic) => {
-      return currentTopicSlug !== topic.slug ? (
-        <li key={topic.databaseId}>
-          <Link href={`/sujet/${topic.slug}`}>
-            <a>{topic.title}</a>
-          </Link>
-        </li>
-      ) : (
-        ''
-      );
-    });
-
-    return <List items={topics} />;
-  };
-
-  return (
-    <ExpandableWidget
-      title={title}
-      titleLevel={titleLevel}
-      withBorders={true}
-      expand={true}
-    >
-      {getList()}
-    </ExpandableWidget>
-  );
-};
-
-export default TopicsList;
diff --git a/src/components/Widgets/index.tsx b/src/components/Widgets/index.tsx
deleted file mode 100644
index 8354449..0000000
--- a/src/components/Widgets/index.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import CVPreview from './CVPreview/CVPreview';
-import RecentPosts from './RecentPosts/RecentPosts';
-import RelatedThematics from './RelatedThematics/RelatedThematics';
-import RelatedTopics from './RelatedTopics/RelatedTopics';
-import Sharing from './Sharing/Sharing';
-import SocialMedia from './SocialMedia/SocialMedia';
-import ThematicsList from './ThematicsList/ThematicsList';
-import ToC from './ToC/ToC';
-import TopicsList from './TopicsList/TopicsList';
-
-export {
-  CVPreview,
-  RecentPosts,
-  RelatedThematics,
-  RelatedTopics,
-  Sharing,
-  SocialMedia,
-  ThematicsList,
-  ToC,
-  TopicsList,
-};
diff --git a/src/pages/404.tsx b/src/pages/404.tsx
deleted file mode 100644
index 24c6951..0000000
--- a/src/pages/404.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-import { getLayout } from '@components/Layouts/Layout';
-import PostHeader from '@components/PostHeader/PostHeader';
-import styles from '@styles/pages/Page.module.scss';
-import { NextPageWithLayout } from '@ts/types/app';
-import { settings } from '@utils/config';
-import { getIntlInstance, loadTranslation } from '@utils/helpers/i18n';
-import { GetStaticProps, GetStaticPropsContext } from 'next';
-import Head from 'next/head';
-import Link from 'next/link';
-import { FormattedMessage, useIntl } from 'react-intl';
-
-const Error404: NextPageWithLayout = () => {
-  const intl = useIntl();
-
-  const pageTitle = intl.formatMessage(
-    {
-      defaultMessage: 'Error 404: Page not found - {websiteName}',
-      description: '404Page: SEO - Page title',
-      id: '310o3F',
-    },
-    { websiteName: settings.name }
-  );
-  const pageDescription = intl.formatMessage({
-    defaultMessage: 'Page not found.',
-    description: '404Page: SEO - Meta description',
-    id: '48Ww//',
-  });
-
-  return (
-    <>
-      <Head>
-        <title>{pageTitle}</title>
-        <meta name="description" content={pageDescription} />
-      </Head>
-      <div className={`${styles.article} ${styles['article--no-comments']}`}>
-        <PostHeader
-          title={intl.formatMessage({
-            defaultMessage: 'Page not found',
-            description: '404Page: page title',
-            id: 'OccTWi',
-          })}
-        />
-        <div className={styles.body}>
-          <FormattedMessage
-            defaultMessage="Sorry, it seems that the page your are looking for does not exist. If you think this path should work, feel free to <link>contact me</link> with the necessary information so that I can fix the problem."
-            description="404Page: page body"
-            id="ZWh78Y"
-            values={{
-              link: (chunks: string) => (
-                <Link href="/contact/">
-                  <a>{chunks}</a>
-                </Link>
-              ),
-            }}
-          />
-        </div>
-      </div>
-    </>
-  );
-};
-
-Error404.getLayout = getLayout;
-
-export const getStaticProps: GetStaticProps = async (
-  context: GetStaticPropsContext
-) => {
-  const intl = await getIntlInstance();
-  const breadcrumbTitle = intl.formatMessage({
-    defaultMessage: 'Error 404',
-    description: '404Page: breadcrumb item',
-    id: 'ywkCsK',
-  });
-  const { locale } = context;
-  const translation = await loadTranslation(locale);
-
-  return {
-    props: {
-      breadcrumbTitle,
-      locale,
-      translation,
-    },
-  };
-};
-
-export default Error404;
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 84c2469..939b337 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,17 +1,16 @@
-import { AppPropsWithLayout } from '@ts/types/app';
 import { settings } from '@utils/config';
 import { AckeeProvider } from '@utils/providers/ackee';
 import { PrismThemeProvider } from '@utils/providers/prism-theme';
 import { ThemeProvider } from 'next-themes';
+import { AppProps } from 'next/app';
 import { useRouter } from 'next/router';
 import { IntlProvider } from 'react-intl';
 import '../styles/globals.scss';
 
-const MyApp = ({ Component, pageProps }: AppPropsWithLayout) => {
+const App = ({ Component, pageProps }: AppProps) => {
   const { locale, defaultLocale } = useRouter();
   const appLocale: string = locale || settings.locales.defaultLocale;
 
-  const getLayout = Component.getLayout ?? ((page) => page);
   return (
     <AckeeProvider domain={settings.ackee.url} siteId={settings.ackee.siteId}>
       <IntlProvider
@@ -25,7 +24,7 @@ const MyApp = ({ Component, pageProps }: AppPropsWithLayout) => {
           enableSystem={true}
         >
           <PrismThemeProvider>
-            {getLayout(<Component {...pageProps} />)}
+            <Component {...pageProps} />
           </PrismThemeProvider>
         </ThemeProvider>
       </IntlProvider>
@@ -33,4 +32,4 @@ const MyApp = ({ Component, pageProps }: AppPropsWithLayout) => {
   );
 };
 
-export default MyApp;
+export default App;
diff --git a/src/pages/article/[slug].tsx b/src/pages/article/[slug].tsx
deleted file mode 100644
index 27a6f7b..0000000
--- a/src/pages/article/[slug].tsx
+++ /dev/null
@@ -1,291 +0,0 @@
-import CommentForm from '@components/CommentForm/CommentForm';
-import CommentsList from '@components/CommentsList/CommentsList';
-import { getLayout } from '@components/Layouts/Layout';
-import PostFooter from '@components/PostFooter/PostFooter';
-import PostHeader from '@components/PostHeader/PostHeader';
-import Sidebar from '@components/Sidebar/Sidebar';
-import Spinner from '@components/Spinner/Spinner';
-import { Sharing, ToC } from '@components/Widgets';
-import {
-  getAllPostsSlug,
-  getCommentsByPostId,
-  getPostBySlug,
-} from '@services/graphql/queries';
-import styles from '@styles/pages/Page.module.scss';
-import { NextPageWithLayout } from '@ts/types/app';
-import { ArticleMeta, ArticleProps } from '@ts/types/articles';
-import { PrismDefaultPlugins, PrismPlugins } from '@ts/types/prism';
-import { settings } from '@utils/config';
-import { getFormattedPaths } from '@utils/helpers/format';
-import { loadTranslation } from '@utils/helpers/i18n';
-import { addPrismClasses } from '@utils/helpers/prism';
-import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from 'next';
-import Head from 'next/head';
-import { useRouter } from 'next/router';
-import Script from 'next/script';
-import Prism from 'prismjs';
-import { ParsedUrlQuery } from 'querystring';
-import { useCallback, useEffect, useMemo } from 'react';
-import { useIntl } from 'react-intl';
-import { Blog, BlogPosting, Graph, WebPage } from 'schema-dts';
-
-const SingleArticle: NextPageWithLayout<ArticleProps> = ({
-  comments,
-  post,
-}) => {
-  const intl = useIntl();
-  const router = useRouter();
-
-  const loadPrismPlugins = useCallback(
-    async (prismPlugins: (PrismDefaultPlugins | PrismPlugins)[]) => {
-      for (const plugin of prismPlugins) {
-        try {
-          if (plugin === 'color-scheme') {
-            await import(`@utils/plugins/prism-${plugin}`);
-          } else {
-            await import(`prismjs/plugins/${plugin}/prism-${plugin}.min.js`);
-
-            if (plugin === 'autoloader')
-              Prism.plugins.autoloader.languages_path = '/prism/';
-          }
-        } catch (error) {
-          console.error('Article: an error occurred with Prism.');
-          console.error(error);
-        }
-      }
-    },
-    []
-  );
-
-  const plugins: (PrismDefaultPlugins | PrismPlugins)[] = useMemo(
-    () => [
-      'autoloader',
-      'toolbar',
-      'show-language',
-      'copy-to-clipboard',
-      'color-scheme',
-      'command-line',
-      'line-numbers',
-      'match-braces',
-      'normalize-whitespace',
-    ],
-    []
-  );
-
-  useEffect(() => {
-    loadPrismPlugins(plugins).then(() => {
-      addPrismClasses();
-      Prism.highlightAll();
-    });
-  }, [plugins, loadPrismPlugins]);
-
-  if (router.isFallback) return <Spinner />;
-
-  const {
-    author,
-    commentCount,
-    content,
-    databaseId,
-    dates,
-    featuredImage,
-    info,
-    intro,
-    seo,
-    topics,
-    thematics,
-    title,
-  } = post;
-
-  const meta: ArticleMeta = {
-    author,
-    commentCount: commentCount || undefined,
-    dates,
-    readingTime: info.readingTime,
-    thematics,
-    wordsCount: info.wordsCount,
-  };
-
-  const articleUrl = `${settings.url}${router.asPath}`;
-
-  const webpageSchema: WebPage = {
-    '@id': `${articleUrl}`,
-    '@type': 'WebPage',
-    breadcrumb: { '@id': `${settings.url}/#breadcrumb` },
-    lastReviewed: dates.update,
-    name: seo.title,
-    description: seo.metaDesc,
-    reviewedBy: { '@id': `${settings.url}/#branding` },
-    url: `${articleUrl}`,
-    isPartOf: {
-      '@id': `${settings.url}`,
-    },
-  };
-
-  const blogSchema: Blog = {
-    '@id': `${settings.url}/#blog`,
-    '@type': 'Blog',
-    blogPost: { '@id': `${settings.url}/#article` },
-    isPartOf: {
-      '@id': `${articleUrl}`,
-    },
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-  };
-
-  const publicationDate = new Date(dates.publication);
-  const updateDate = new Date(dates.update);
-
-  const blogPostSchema: BlogPosting = {
-    '@id': `${settings.url}/#article`,
-    '@type': 'BlogPosting',
-    name: title,
-    description: intro,
-    articleBody: content,
-    author: { '@id': `${settings.url}/#branding` },
-    commentCount: commentCount || undefined,
-    copyrightYear: publicationDate.getFullYear(),
-    creator: { '@id': `${settings.url}/#branding` },
-    dateCreated: publicationDate.toISOString(),
-    dateModified: updateDate.toISOString(),
-    datePublished: publicationDate.toISOString(),
-    discussionUrl: `${articleUrl}/#comments`,
-    editor: { '@id': `${settings.url}/#branding` },
-    headline: title,
-    image: featuredImage?.sourceUrl,
-    inLanguage: settings.locales.defaultLocale,
-    isPartOf: {
-      '@id': `${settings.url}/blog`,
-    },
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-    mainEntityOfPage: { '@id': `${articleUrl}` },
-    thumbnailUrl: featuredImage?.sourceUrl,
-  };
-
-  const schemaJsonLd: Graph = {
-    '@context': 'https://schema.org',
-    '@graph': [webpageSchema, blogSchema, blogPostSchema],
-  };
-
-  const copyText = intl.formatMessage({
-    defaultMessage: 'Copy',
-    description: 'Prism: copy button text (no clicked)',
-    id: '/ly3AC',
-  });
-  const copiedText = intl.formatMessage({
-    defaultMessage: 'Copied!',
-    description: 'Prism: copy button text (clicked)',
-    id: 'OV9r1K',
-  });
-  const errorText = intl.formatMessage({
-    defaultMessage: 'Use Ctrl+c to copy',
-    description: 'Prism: error text',
-    id: 'z9qkcQ',
-  });
-  const darkTheme = intl.formatMessage({
-    defaultMessage: 'Dark Theme 🌙',
-    description: 'Prism: toggle dark theme button text',
-    id: 'nFMdWI',
-  });
-  const lightTheme = intl.formatMessage({
-    defaultMessage: 'Light Theme 🌞',
-    description: 'Prism: toggle light theme button text',
-    id: 'Ua2g2p',
-  });
-
-  return (
-    <>
-      <Head>
-        <title>{seo.title}</title>
-        <meta name="description" content={seo.metaDesc} />
-        <meta property="og:url" content={`${articleUrl}`} />
-        <meta property="og:type" content="article" />
-        <meta property="og:title" content={title} />
-        <meta property="og:description" content={intro} />
-        <meta property="og:image" content={featuredImage?.sourceUrl} />
-        <meta property="og:image:alt" content={featuredImage?.altText} />
-      </Head>
-      <Script
-        id="schema-article"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      <article
-        id="article"
-        className={styles.article}
-        data-prismjs-copy={copyText}
-        data-prismjs-copy-success={copiedText}
-        data-prismjs-copy-error={errorText}
-        data-prismjs-color-scheme-dark={darkTheme}
-        data-prismjs-color-scheme-light={lightTheme}
-      >
-        <PostHeader intro={intro} meta={meta} title={title} />
-        <Sidebar
-          position="left"
-          ariaLabel={intl.formatMessage({
-            defaultMessage: 'Table of Contents',
-            description: 'ArticlePage: ToC sidebar aria-label',
-            id: '9nhYRA',
-          })}
-        >
-          <ToC />
-        </Sidebar>
-        <div
-          className={styles.body}
-          dangerouslySetInnerHTML={{ __html: content }}
-        ></div>
-        <PostFooter topics={topics} />
-        <Sidebar
-          position="right"
-          ariaLabel={intl.formatMessage({
-            defaultMessage: 'Sidebar',
-            description: 'ArticlePage: right sidebar aria-label',
-            id: 'JeYOeA',
-          })}
-        >
-          <Sharing title={title} excerpt={intro} />
-        </Sidebar>
-        <section id="comments" className={styles.comments}>
-          <CommentsList articleId={databaseId} comments={comments} />
-          <CommentForm articleId={databaseId} />
-        </section>
-      </article>
-    </>
-  );
-};
-
-SingleArticle.getLayout = getLayout;
-
-interface PostParams extends ParsedUrlQuery {
-  slug: string;
-}
-
-export const getStaticProps: GetStaticProps = async (
-  context: GetStaticPropsContext
-) => {
-  const { locale } = context;
-  const translation = await loadTranslation(locale);
-  const { slug } = context.params as PostParams;
-  const post = await getPostBySlug(slug);
-  const comments = await getCommentsByPostId(post.databaseId);
-  const breadcrumbTitle = post.title;
-
-  return {
-    props: {
-      breadcrumbTitle,
-      comments,
-      post,
-      translation,
-    },
-  };
-};
-
-export const getStaticPaths: GetStaticPaths = async () => {
-  const allSlugs = await getAllPostsSlug();
-  const paths = getFormattedPaths(allSlugs);
-
-  return {
-    paths,
-    fallback: true,
-  };
-};
-
-export default SingleArticle;
diff --git a/src/pages/blog/index.tsx b/src/pages/blog/index.tsx
deleted file mode 100644
index b5ced07..0000000
--- a/src/pages/blog/index.tsx
+++ /dev/null
@@ -1,269 +0,0 @@
-import { Button } from '@components/Buttons';
-import { getLayout } from '@components/Layouts/Layout';
-import Pagination from '@components/Pagination/Pagination';
-import PaginationCursor from '@components/PaginationCursor/PaginationCursor';
-import PostHeader from '@components/PostHeader/PostHeader';
-import PostsList from '@components/PostsList/PostsList';
-import Sidebar from '@components/Sidebar/Sidebar';
-import Spinner from '@components/Spinner/Spinner';
-import { ThematicsList, TopicsList } from '@components/Widgets';
-import {
-  getAllThematics,
-  getAllTopics,
-  getPostsTotal,
-  getPublishedPosts,
-} from '@services/graphql/queries';
-import styles from '@styles/pages/Page.module.scss';
-import { NextPageWithLayout } from '@ts/types/app';
-import { BlogPageProps, PostsList as PostsListData } from '@ts/types/blog';
-import { settings } from '@utils/config';
-import { getIntlInstance, loadTranslation } from '@utils/helpers/i18n';
-import { GetStaticProps, GetStaticPropsContext } from 'next';
-import Head from 'next/head';
-import { useRouter } from 'next/router';
-import Script from 'next/script';
-import { useEffect, useRef, useState } from 'react';
-import { useIntl } from 'react-intl';
-import { Blog as BlogSchema, Graph, WebPage } from 'schema-dts';
-import useSWRInfinite from 'swr/infinite';
-
-const Blog: NextPageWithLayout<BlogPageProps> = ({
-  allThematics,
-  allTopics,
-  posts,
-  totalPosts,
-}) => {
-  const intl = useIntl();
-  const lastPostRef = useRef<HTMLSpanElement>(null);
-  const router = useRouter();
-  const [isMounted, setIsMounted] = useState<boolean>(false);
-
-  useEffect(() => {
-    if (typeof window !== undefined) setIsMounted(true);
-  }, []);
-
-  const getKey = (pageIndex: number, previousData: PostsListData) => {
-    if (previousData && !previousData.posts) return null;
-
-    return pageIndex === 0
-      ? { first: settings.postsPerPage }
-      : {
-          first: settings.postsPerPage,
-          after: previousData.pageInfo.endCursor,
-        };
-  };
-
-  const { data, error, size, setSize } = useSWRInfinite(
-    getKey,
-    getPublishedPosts,
-    { fallbackData: [posts] }
-  );
-  const [totalPostsCount, setTotalPostsCount] = useState<number>(totalPosts);
-
-  useEffect(() => {
-    if (data) setTotalPostsCount(data[0].pageInfo.total);
-  }, [data]);
-
-  const [loadedPostsCount, setLoadedPostsCount] = useState<number>(
-    settings.postsPerPage
-  );
-
-  useEffect(() => {
-    if (data && data.length > 0) {
-      const newCount =
-        settings.postsPerPage +
-        data[0].pageInfo.total -
-        data[data.length - 1].pageInfo.total;
-      setLoadedPostsCount(newCount);
-    }
-  }, [data]);
-
-  const isLoadingInitialData = !data && !error;
-  const isLoadingMore: boolean =
-    isLoadingInitialData ||
-    (size > 0 && data !== undefined && typeof data[size - 1] === 'undefined');
-
-  const hasNextPage = data && data[data.length - 1].pageInfo.hasNextPage;
-
-  const loadMorePosts = () => {
-    if (lastPostRef.current) {
-      lastPostRef.current.focus();
-    }
-    setSize(size + 1);
-  };
-
-  const getPostsList = () => {
-    if (error)
-      return intl.formatMessage({
-        defaultMessage: 'Failed to load.',
-        description: 'BlogPage: failed to load text',
-        id: 'C/XGkH',
-      });
-    if (!data) return <Spinner />;
-
-    return <PostsList ref={lastPostRef} data={data} showYears={true} />;
-  };
-
-  const pageTitle = intl.formatMessage(
-    {
-      defaultMessage: 'Blog: development, open source - {websiteName}',
-      description: 'BlogPage: SEO - Page title',
-      id: '+Y+tLK',
-    },
-    { websiteName: settings.name }
-  );
-  const pageDescription = intl.formatMessage(
-    {
-      defaultMessage:
-        "Discover {websiteName}'s writings. He talks about web development, Linux and open source mostly.",
-      description: 'BlogPage: SEO - Meta description',
-      id: '18h/t0',
-    },
-    { websiteName: settings.name }
-  );
-  const pageUrl = `${settings.url}${router.asPath}`;
-
-  const webpageSchema: WebPage = {
-    '@id': `${pageUrl}`,
-    '@type': 'WebPage',
-    breadcrumb: { '@id': `${settings.url}/#breadcrumb` },
-    name: pageTitle,
-    description: pageDescription,
-    inLanguage: settings.locales.defaultLocale,
-    reviewedBy: { '@id': `${settings.url}/#branding` },
-    url: `${settings.url}`,
-    isPartOf: {
-      '@id': `${settings.url}`,
-    },
-  };
-
-  const blogSchema: BlogSchema = {
-    '@id': `${settings.url}/#blog`,
-    '@type': 'Blog',
-    author: { '@id': `${settings.url}/#branding` },
-    creator: { '@id': `${settings.url}/#branding` },
-    editor: { '@id': `${settings.url}/#branding` },
-    inLanguage: settings.locales.defaultLocale,
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-    mainEntityOfPage: { '@id': `${pageUrl}` },
-  };
-
-  const schemaJsonLd: Graph = {
-    '@context': 'https://schema.org',
-    '@graph': [webpageSchema, blogSchema],
-  };
-
-  const title = intl.formatMessage({
-    defaultMessage: 'Blog',
-    description: 'BlogPage: page title',
-    id: '7TbbIk',
-  });
-
-  return (
-    <>
-      <Head>
-        <title>{pageTitle}</title>
-        <meta name="description" content={pageDescription} />
-        <meta property="og:url" content={`${pageUrl}`} />
-        <meta property="og:type" content="website" />
-        <meta property="og:title" content={title} />
-        <meta property="og:description" content={pageDescription} />
-      </Head>
-      <Script
-        id="schema-blog"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      <article
-        id="blog"
-        className={`${styles.article} ${styles['article--no-comments']}`}
-      >
-        <PostHeader title={title} meta={{ results: totalPostsCount }} />
-        <div className={styles.body}>
-          {getPostsList()}
-          {hasNextPage &&
-            (isMounted ? (
-              <>
-                <PaginationCursor
-                  current={loadedPostsCount}
-                  total={totalPostsCount}
-                />
-                <Button
-                  isDisabled={isLoadingMore}
-                  clickHandler={loadMorePosts}
-                  position="center"
-                  spacing={true}
-                >
-                  {intl.formatMessage({
-                    defaultMessage: 'Load more?',
-                    description: 'BlogPage: load more text',
-                    id: 'Kqq2cm',
-                  })}
-                </Button>
-              </>
-            ) : (
-              <Pagination baseUrl="/blog" total={totalPostsCount} />
-            ))}
-        </div>
-        <Sidebar
-          position="right"
-          title={intl.formatMessage({
-            defaultMessage: 'Filter by:',
-            description: 'BlogPage: sidebar title',
-            id: 'KERk7L',
-          })}
-        >
-          <ThematicsList
-            initialData={allThematics}
-            title={intl.formatMessage({
-              defaultMessage: 'Thematics',
-              description: 'BlogPage: thematics list widget title',
-              id: 'HriY57',
-            })}
-          />
-          <TopicsList
-            initialData={allTopics}
-            title={intl.formatMessage({
-              defaultMessage: 'Topics',
-              description: 'BlogPage: topics list widget title',
-              id: '2D9tB5',
-            })}
-          />
-        </Sidebar>
-      </article>
-    </>
-  );
-};
-
-Blog.getLayout = getLayout;
-
-export const getStaticProps: GetStaticProps = async (
-  context: GetStaticPropsContext
-) => {
-  const intl = await getIntlInstance();
-  const breadcrumbTitle = intl.formatMessage({
-    defaultMessage: 'Blog',
-    description: 'BlogPage: breadcrumb item',
-    id: 'R0eDmw',
-  });
-  const firstPosts = await getPublishedPosts({ first: settings.postsPerPage });
-  const totalPosts = await getPostsTotal();
-  const allThematics = await getAllThematics();
-  const allTopics = await getAllTopics();
-  const { locale } = context;
-  const translation = await loadTranslation(locale);
-
-  return {
-    props: {
-      allThematics,
-      allTopics,
-      breadcrumbTitle,
-      locale,
-      posts: firstPosts,
-      totalPosts,
-      translation,
-    },
-  };
-};
-
-export default Blog;
diff --git a/src/pages/blog/page/[id].tsx b/src/pages/blog/page/[id].tsx
deleted file mode 100644
index 6c4d2f8..0000000
--- a/src/pages/blog/page/[id].tsx
+++ /dev/null
@@ -1,205 +0,0 @@
-import { getLayout } from '@components/Layouts/Layout';
-import Pagination from '@components/Pagination/Pagination';
-import PostHeader from '@components/PostHeader/PostHeader';
-import PostsList from '@components/PostsList/PostsList';
-import Sidebar from '@components/Sidebar/Sidebar';
-import { ThematicsList, TopicsList } from '@components/Widgets';
-import {
-  getAllThematics,
-  getAllTopics,
-  getEndCursor,
-  getPostsTotal,
-  getPublishedPosts,
-} from '@services/graphql/queries';
-import { NextPageWithLayout } from '@ts/types/app';
-import { BlogPageProps } from '@ts/types/blog';
-import { settings } from '@utils/config';
-import { getIntlInstance, loadTranslation } from '@utils/helpers/i18n';
-import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from 'next';
-import Head from 'next/head';
-import { useRouter } from 'next/router';
-import Script from 'next/script';
-import { useIntl } from 'react-intl';
-import { Blog, Graph, WebPage } from 'schema-dts';
-import styles from '@styles/pages/Page.module.scss';
-import { getFormattedPageNumbers } from '@utils/helpers/format';
-import { useEffect } from 'react';
-import Spinner from '@components/Spinner/Spinner';
-
-const BlogPage: NextPageWithLayout<BlogPageProps> = ({
-  allThematics,
-  allTopics,
-  posts,
-  totalPosts,
-}) => {
-  const intl = useIntl();
-  const router = useRouter();
-  const pageNumber = Number(router.query.id);
-
-  useEffect(() => {
-    if (router.query.id === '1') router.push('/blog');
-  }, [router]);
-
-  if (router.isFallback) return <Spinner />;
-
-  const pageTitle = intl.formatMessage(
-    {
-      defaultMessage: 'Blog - Page {number} - {websiteName}',
-      description: 'BlogPage: SEO - Page title',
-      id: '8w+jnD',
-    },
-    { number: pageNumber, websiteName: settings.name }
-  );
-  const pageDescription = intl.formatMessage(
-    {
-      defaultMessage:
-        "Discover {websiteName}'s writings. He talks about web development, Linux and open source mostly.",
-      description: 'BlogPage: SEO - Meta description',
-      id: '18h/t0',
-    },
-    { websiteName: settings.name }
-  );
-  const pageUrl = `${settings.url}${router.asPath}`;
-
-  const webpageSchema: WebPage = {
-    '@id': `${pageUrl}`,
-    '@type': 'WebPage',
-    breadcrumb: { '@id': `${settings.url}/#breadcrumb` },
-    name: pageTitle,
-    description: pageDescription,
-    inLanguage: settings.locales.defaultLocale,
-    reviewedBy: { '@id': `${settings.url}/#branding` },
-    url: `${settings.url}`,
-    isPartOf: {
-      '@id': `${settings.url}`,
-    },
-  };
-
-  const blogSchema: Blog = {
-    '@id': `${settings.url}/#blog`,
-    '@type': 'Blog',
-    author: { '@id': `${settings.url}/#branding` },
-    creator: { '@id': `${settings.url}/#branding` },
-    editor: { '@id': `${settings.url}/#branding` },
-    inLanguage: settings.locales.defaultLocale,
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-    mainEntityOfPage: { '@id': `${pageUrl}` },
-  };
-
-  const schemaJsonLd: Graph = {
-    '@context': 'https://schema.org',
-    '@graph': [webpageSchema, blogSchema],
-  };
-
-  const title = intl.formatMessage({
-    defaultMessage: 'Blog',
-    description: 'BlogPage: page title',
-    id: '7TbbIk',
-  });
-
-  return (
-    <>
-      <Head>
-        <title>{pageTitle}</title>
-        <meta name="description" content={pageDescription} />
-        <meta property="og:url" content={`${pageUrl}`} />
-        <meta property="og:type" content="website" />
-        <meta property="og:title" content={title} />
-        <meta property="og:description" content={pageDescription} />
-      </Head>
-      <Script
-        id="schema-blog"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      <article
-        id="blog"
-        className={`${styles.article} ${styles['article--no-comments']}`}
-      >
-        <PostHeader title={title} meta={{ results: totalPosts }} />
-        <div className={styles.body}>
-          <PostsList data={[posts]} showYears={true} />
-          <Pagination baseUrl="/blog" total={totalPosts} />
-        </div>
-        <Sidebar
-          position="right"
-          title={intl.formatMessage({
-            defaultMessage: 'Filter by:',
-            description: 'BlogPage: sidebar title',
-            id: 'KERk7L',
-          })}
-        >
-          <ThematicsList
-            initialData={allThematics}
-            title={intl.formatMessage({
-              defaultMessage: 'Thematics',
-              description: 'BlogPage: thematics list widget title',
-              id: 'HriY57',
-            })}
-          />
-          <TopicsList
-            initialData={allTopics}
-            title={intl.formatMessage({
-              defaultMessage: 'Topics',
-              description: 'BlogPage: topics list widget title',
-              id: '2D9tB5',
-            })}
-          />
-        </Sidebar>
-      </article>
-    </>
-  );
-};
-
-BlogPage.getLayout = getLayout;
-
-export const getStaticProps: GetStaticProps = async (
-  context: GetStaticPropsContext
-) => {
-  const intl = await getIntlInstance();
-  const breadcrumbTitle = intl.formatMessage({
-    defaultMessage: 'Blog',
-    description: 'BlogPage: breadcrumb item',
-    id: 'R0eDmw',
-  });
-  const { locale, params } = context;
-  const queriedPageNumber = params ? Number(params.id) : 1;
-  const queriedPostsNumber = settings.postsPerPage * queriedPageNumber;
-  const endCursor =
-    queriedPostsNumber === 1
-      ? undefined
-      : await getEndCursor({ first: queriedPostsNumber });
-  const posts = await getPublishedPosts({
-    first: settings.postsPerPage,
-    after: endCursor,
-  });
-  const totalPosts = await getPostsTotal();
-  const allThematics = await getAllThematics();
-  const allTopics = await getAllTopics();
-  const translation = await loadTranslation(locale);
-
-  return {
-    props: {
-      allThematics,
-      allTopics,
-      breadcrumbTitle,
-      locale,
-      posts,
-      totalPosts,
-      translation,
-    },
-  };
-};
-
-export default BlogPage;
-
-export const getStaticPaths: GetStaticPaths = async () => {
-  const totalPosts = await getPostsTotal();
-  const totalPages = Math.floor(totalPosts / settings.postsPerPage);
-  const paths = getFormattedPageNumbers(totalPages);
-
-  return {
-    paths,
-    fallback: true,
-  };
-};
diff --git a/src/pages/contact.tsx b/src/pages/contact.tsx
deleted file mode 100644
index 5934dd9..0000000
--- a/src/pages/contact.tsx
+++ /dev/null
@@ -1,151 +0,0 @@
-import ContactForm from '@components/ContactForm/ContactForm';
-import { getLayout } from '@components/Layouts/Layout';
-import PostHeader from '@components/PostHeader/PostHeader';
-import Sidebar from '@components/Sidebar/Sidebar';
-import { SocialMedia } from '@components/Widgets';
-import styles from '@styles/pages/Page.module.scss';
-import { NextPageWithLayout } from '@ts/types/app';
-import { settings } from '@utils/config';
-import { getIntlInstance, loadTranslation } from '@utils/helpers/i18n';
-import { GetStaticProps, GetStaticPropsContext } from 'next';
-import Head from 'next/head';
-import { useRouter } from 'next/router';
-import Script from 'next/script';
-import { useIntl } from 'react-intl';
-import { ContactPage as ContactPageSchema, Graph, WebPage } from 'schema-dts';
-
-const ContactPage: NextPageWithLayout = () => {
-  const intl = useIntl();
-  const router = useRouter();
-
-  const pageTitle = intl.formatMessage(
-    {
-      defaultMessage: 'Contact form - {websiteName}',
-      description: 'ContactPage: SEO - Page title',
-      id: 'Y3qRib',
-    },
-    { websiteName: settings.name }
-  );
-  const pageDescription = intl.formatMessage(
-    {
-      defaultMessage:
-        "Contact {websiteName} through its website. All you need to do it's to fill the contact form.",
-      description: 'ContactPage: SEO - Meta description',
-      id: 'OIffB4',
-    },
-    { websiteName: settings.name }
-  );
-  const pageUrl = `${settings.url}${router.asPath}`;
-  const title = intl.formatMessage({
-    defaultMessage: 'Contact',
-    description: 'ContactPage: page title',
-    id: 'AN9iy7',
-  });
-  const intro = intl.formatMessage({
-    defaultMessage: 'Please fill the form to contact me.',
-    description: 'ContactPage: page introduction',
-    id: '8Ls2mD',
-  });
-
-  const webpageSchema: WebPage = {
-    '@id': `${pageUrl}`,
-    '@type': 'WebPage',
-    breadcrumb: { '@id': `${settings.url}/#breadcrumb` },
-    name: pageTitle,
-    description: pageDescription,
-    reviewedBy: { '@id': `${settings.url}/#branding` },
-    url: `${pageUrl}`,
-    isPartOf: {
-      '@id': `${settings.url}`,
-    },
-  };
-
-  const contactSchema: ContactPageSchema = {
-    '@id': `${settings.url}/#contact`,
-    '@type': 'ContactPage',
-    name: title,
-    description: intro,
-    author: { '@id': `${settings.url}/#branding` },
-    creator: { '@id': `${settings.url}/#branding` },
-    editor: { '@id': `${settings.url}/#branding` },
-    inLanguage: settings.locales.defaultLocale,
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-    mainEntityOfPage: { '@id': `${pageUrl}` },
-  };
-
-  const schemaJsonLd: Graph = {
-    '@context': 'https://schema.org',
-    '@graph': [webpageSchema, contactSchema],
-  };
-
-  return (
-    <>
-      <Head>
-        <title>{pageTitle}</title>
-        <meta name="description" content={pageDescription} />
-        <meta property="og:url" content={`${pageUrl}`} />
-        <meta property="og:type" content="article" />
-        <meta property="og:title" content={title} />
-        <meta property="og:description" content={intro} />
-      </Head>
-      <Script
-        id="schema-contact"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      <article
-        id="contact"
-        className={`${styles.article} ${styles['article--no-comments']}`}
-      >
-        <PostHeader title={title} intro={intro} />
-        <div className={styles.body}>
-          <p>
-            {intl.formatMessage({
-              defaultMessage: 'All fields marked with * are required.',
-              description: 'ContactPage: required fields text',
-              id: 'txusHd',
-            })}
-          </p>
-          <ContactForm />
-        </div>
-        <Sidebar position="right">
-          <SocialMedia
-            title={intl.formatMessage({
-              defaultMessage: 'Find me elsewhere',
-              description: 'ContactPage: social media widget title',
-              id: 'Qh2CwH',
-            })}
-            github={true}
-            gitlab={true}
-            linkedin={true}
-          />
-        </Sidebar>
-      </article>
-    </>
-  );
-};
-
-ContactPage.getLayout = getLayout;
-
-export const getStaticProps: GetStaticProps = async (
-  context: GetStaticPropsContext
-) => {
-  const intl = await getIntlInstance();
-  const breadcrumbTitle = intl.formatMessage({
-    defaultMessage: 'Contact',
-    description: 'ContactPage: breadcrumb item',
-    id: 'CzTbM4',
-  });
-  const { locale } = context;
-  const translation = await loadTranslation(locale);
-
-  return {
-    props: {
-      breadcrumbTitle,
-      locale,
-      translation,
-    },
-  };
-};
-
-export default ContactPage;
diff --git a/src/pages/cv.tsx b/src/pages/cv.tsx
deleted file mode 100644
index 71eb449..0000000
--- a/src/pages/cv.tsx
+++ /dev/null
@@ -1,181 +0,0 @@
-import { getLayout } from '@components/Layouts/Layout';
-import PostHeader from '@components/PostHeader/PostHeader';
-import Sidebar from '@components/Sidebar/Sidebar';
-import { CVPreview, SocialMedia, ToC } from '@components/Widgets';
-import CVContent, { intro, meta, pdf, image } from '@content/pages/cv.mdx';
-import styles from '@styles/pages/Page.module.scss';
-import { NextPageWithLayout } from '@ts/types/app';
-import { ArticleMeta } from '@ts/types/articles';
-import { settings } from '@utils/config';
-import { loadTranslation } from '@utils/helpers/i18n';
-import { GetStaticProps, GetStaticPropsContext } from 'next';
-import Head from 'next/head';
-import { useRouter } from 'next/router';
-import Script from 'next/script';
-import { useIntl } from 'react-intl';
-import { AboutPage, Graph, WebPage } from 'schema-dts';
-
-const CV: NextPageWithLayout = () => {
-  const intl = useIntl();
-  const router = useRouter();
-  const dates = {
-    publication: meta.publishedOn,
-    update: meta.updatedOn,
-  };
-
-  const pageMeta: ArticleMeta = {
-    dates,
-  };
-  const pageUrl = `${settings.url}${router.asPath}`;
-  const pageTitle = intl.formatMessage(
-    {
-      defaultMessage: 'CV Front-end developer - {websiteName}',
-      description: 'CVPage: SEO - Page title',
-      id: 'Y1ZdJ6',
-    },
-    { websiteName: settings.name }
-  );
-  const pageDescription = intl.formatMessage(
-    {
-      defaultMessage:
-        'Discover the curriculum of {websiteName}, front-end developer located in France: skills, experiences and training.',
-      description: 'CVPage: SEO - Meta description',
-      id: 'bBdMGm',
-    },
-    { websiteName: settings.name }
-  );
-
-  const webpageSchema: WebPage = {
-    '@id': `${pageUrl}`,
-    '@type': 'WebPage',
-    breadcrumb: { '@id': `${settings.url}/#breadcrumb` },
-    name: pageTitle,
-    description: pageDescription,
-    reviewedBy: { '@id': `${settings.url}/#branding` },
-    url: `${pageUrl}`,
-    isPartOf: {
-      '@id': `${settings.url}`,
-    },
-  };
-
-  const publicationDate = new Date(dates.publication);
-  const updateDate = new Date(dates.update);
-
-  const cvSchema: AboutPage = {
-    '@id': `${settings.url}/#cv`,
-    '@type': 'AboutPage',
-    name: pageTitle,
-    description: intro,
-    author: { '@id': `${settings.url}/#branding` },
-    creator: { '@id': `${settings.url}/#branding` },
-    dateCreated: publicationDate.toISOString(),
-    dateModified: updateDate.toISOString(),
-    datePublished: publicationDate.toISOString(),
-    editor: { '@id': `${settings.url}/#branding` },
-    image,
-    inLanguage: settings.locales.defaultLocale,
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-    thumbnailUrl: image,
-    mainEntityOfPage: { '@id': `${pageUrl}` },
-  };
-
-  const schemaJsonLd: Graph = {
-    '@context': 'https://schema.org',
-    '@graph': [webpageSchema, cvSchema],
-  };
-
-  const title = intl.formatMessage(
-    {
-      defaultMessage: "{name}'s CV",
-      description: 'CVPage: page title',
-      id: 'Mj2BQf',
-    },
-    { name: settings.name }
-  );
-
-  return (
-    <>
-      <Head>
-        <title>{pageTitle}</title>
-        <meta name="description" content={pageDescription} />
-        <meta property="og:url" content={`${pageUrl}`} />
-        <meta property="og:type" content="article" />
-        <meta property="og:title" content={title} />
-        <meta property="og:description" content={intro} />
-        <meta property="og:image" content={image} />
-        <meta property="og:image:alt" content={title} />
-      </Head>
-      <Script
-        id="schema-cv"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      <article
-        id="cv"
-        className={`${styles.article} ${styles['article--no-comments']}`}
-      >
-        <PostHeader intro={intro} meta={pageMeta} title={meta.title} />
-        <Sidebar
-          position="left"
-          ariaLabel={intl.formatMessage({
-            defaultMessage: 'Table of Contents',
-            description: 'CVPage: ToC sidebar aria-label',
-            id: 'g4DckL',
-          })}
-        >
-          <ToC />
-        </Sidebar>
-        <div className={styles.body}>
-          <CVContent />
-        </div>
-        <Sidebar
-          position="right"
-          ariaLabel={intl.formatMessage({
-            defaultMessage: 'Sidebar',
-            description: 'CVPage: right sidebar aria-label',
-            id: 'QHOm5t',
-          })}
-        >
-          <CVPreview
-            title={intl.formatMessage({
-              defaultMessage: 'Others formats',
-              description: 'CVPage: cv preview widget title',
-              id: 'B9OCyV',
-            })}
-            imgSrc={image}
-            pdf={pdf}
-          />
-          <SocialMedia
-            title={intl.formatMessage({
-              defaultMessage: 'Open-source projects',
-              description: 'CVPage: social media widget title',
-              id: '+Dre5J',
-            })}
-            github={true}
-            gitlab={true}
-          />
-        </Sidebar>
-      </article>
-    </>
-  );
-};
-
-CV.getLayout = getLayout;
-
-export const getStaticProps: GetStaticProps = async (
-  context: GetStaticPropsContext
-) => {
-  const breadcrumbTitle = meta.title;
-  const { locale } = context;
-  const translation = await loadTranslation(locale);
-
-  return {
-    props: {
-      breadcrumbTitle,
-      locale,
-      translation,
-    },
-  };
-};
-
-export default CV;
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
deleted file mode 100644
index ca0a809..0000000
--- a/src/pages/index.tsx
+++ /dev/null
@@ -1,241 +0,0 @@
-import FeedIcon from '@assets/images/icon-feed.svg';
-import { ButtonLink } from '@components/Buttons';
-import { ContactIcon } from '@components/Icons';
-import Layout from '@components/Layouts/Layout';
-import { ResponsiveImage } from '@components/MDX';
-import { RecentPosts } from '@components/Widgets';
-import HomePageContent from '@content/pages/homepage.mdx';
-import { getPublishedPosts } from '@services/graphql/queries';
-import styles from '@styles/pages/Home.module.scss';
-import { NextPageWithLayout, ResponsiveImageProps } from '@ts/types/app';
-import { PostsList } from '@ts/types/blog';
-import { settings } from '@utils/config';
-import { loadTranslation } from '@utils/helpers/i18n';
-import { NestedMDXComponents } from 'mdx/types';
-import { GetStaticProps, GetStaticPropsContext } from 'next';
-import Head from 'next/head';
-import Script from 'next/script';
-import type { ReactElement } from 'react';
-import { useIntl } from 'react-intl';
-import { Graph, WebPage } from 'schema-dts';
-
-type HomePageProps = {
-  recentPosts: PostsList;
-};
-
-const Home: NextPageWithLayout<HomePageProps> = ({
-  recentPosts,
-}: {
-  recentPosts: PostsList;
-}) => {
-  const intl = useIntl();
-
-  const CodingLinks = () => {
-    return (
-      <ul className={styles['links-list']}>
-        <li>
-          <ButtonLink target="/thematique/developpement-web">
-            {intl.formatMessage({
-              defaultMessage: 'Web development',
-              description: 'HomePage: link to web development thematic',
-              id: 'vkF/RP',
-            })}
-          </ButtonLink>
-        </li>
-        <li>
-          <ButtonLink target="/projets">
-            {intl.formatMessage({
-              defaultMessage: 'Projects',
-              description: 'HomePage: link to projects',
-              id: 'N44SOc',
-            })}
-          </ButtonLink>
-        </li>
-      </ul>
-    );
-  };
-
-  const ColdarkRepos = () => {
-    return (
-      <ul className={styles['links-list']}>
-        <li>
-          <ButtonLink
-            target="https://github.com/ArmandPhilippot/coldark"
-            isExternal={true}
-          >
-            Github
-          </ButtonLink>
-        </li>
-        <li>
-          <ButtonLink
-            target="https://gitlab.com/ArmandPhilippot/coldark"
-            isExternal={true}
-          >
-            Gitlab
-          </ButtonLink>
-        </li>
-      </ul>
-    );
-  };
-
-  const LibreLinks = () => {
-    return (
-      <ul className={styles['links-list']}>
-        <li>
-          <ButtonLink target="/thematique/libre">
-            {intl.formatMessage({
-              defaultMessage: 'Free',
-              description: 'HomePage: link to free thematic',
-              id: 'w8GrOf',
-            })}
-          </ButtonLink>
-        </li>
-        <li>
-          <ButtonLink target="/thematique/linux">
-            {intl.formatMessage({
-              defaultMessage: 'Linux',
-              description: 'HomePage: link to Linux thematic',
-              id: 'jASD7k',
-            })}
-          </ButtonLink>
-        </li>
-      </ul>
-    );
-  };
-
-  const ShaarliLink = () => {
-    return (
-      <ul className={styles['links-list']}>
-        <li>
-          <ButtonLink target="https://shaarli.armandphilippot.com/">
-            {intl.formatMessage({
-              defaultMessage: 'Shaarli',
-              description: 'HomePage: link to Shaarli',
-              id: 'i5L19t',
-            })}
-          </ButtonLink>
-        </li>
-      </ul>
-    );
-  };
-
-  const MoreLinks = () => {
-    return (
-      <ul className={styles['links-list']}>
-        <li>
-          <ButtonLink target="/contact">
-            <ContactIcon />
-            {intl.formatMessage({
-              defaultMessage: 'Contact me',
-              description: 'HomePage: contact button text',
-              id: 'sO/Iwj',
-            })}
-          </ButtonLink>
-        </li>
-        <li>
-          <ButtonLink target="/feed">
-            <FeedIcon className={styles['icon--feed']} />
-            {intl.formatMessage({
-              defaultMessage: 'Subscribe',
-              description: 'HomePage: RSS feed subscription text',
-              id: 'T4YA64',
-            })}
-          </ButtonLink>
-        </li>
-      </ul>
-    );
-  };
-
-  const getRecentPosts = () => {
-    return <RecentPosts posts={recentPosts} />;
-  };
-
-  const components: NestedMDXComponents = {
-    CodingLinks: CodingLinks,
-    ColdarkRepos: ColdarkRepos,
-    Image: (props: ResponsiveImageProps) => ResponsiveImage({ ...props }),
-    LibreLinks: LibreLinks,
-    MoreLinks: MoreLinks,
-    RecentPosts: getRecentPosts,
-    ShaarliLink: ShaarliLink,
-  };
-
-  const pageTitle = intl.formatMessage(
-    {
-      defaultMessage: '{websiteName} | Front-end developer: WordPress/React',
-      description: 'HomePage: SEO - Page title',
-      id: 'PXp2hv',
-    },
-    { websiteName: settings.name }
-  );
-  const pageDescription = intl.formatMessage(
-    {
-      defaultMessage:
-        '{websiteName} is a front-end developer located in France. He codes and he writes mostly about web development and open-source.',
-      description: 'HomePage: SEO - Meta description',
-      id: 'tMuNTy',
-    },
-    { websiteName: settings.name }
-  );
-
-  const webpageSchema: WebPage = {
-    '@id': `${settings.url}/#home`,
-    '@type': 'WebPage',
-    name: pageTitle,
-    description: pageDescription,
-    author: { '@id': `${settings.url}/#branding` },
-    creator: { '@id': `${settings.url}/#branding` },
-    editor: { '@id': `${settings.url}/#branding` },
-    inLanguage: settings.locales.defaultLocale,
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-    reviewedBy: { '@id': `${settings.url}/#branding` },
-    url: `${settings.url}`,
-  };
-
-  const schemaJsonLd: Graph = {
-    '@context': 'https://schema.org',
-    '@graph': [webpageSchema],
-  };
-
-  return (
-    <>
-      <Head>
-        <title>{pageTitle}</title>
-        <meta name="description" content={pageDescription} />
-        <meta property="og:type" content="website" />
-        <meta property="og:url" content={`${settings.url}`} />
-        <meta property="og:title" content={pageTitle} />
-        <meta property="og:description" content={pageDescription} />
-      </Head>
-      <Script
-        id="schema-homepage"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      <div id="home">
-        <HomePageContent components={components} />
-      </div>
-    </>
-  );
-};
-
-Home.getLayout = function getLayout(page: ReactElement) {
-  return <Layout isHome={true}>{page}</Layout>;
-};
-
-export const getStaticProps: GetStaticProps = async (
-  context: GetStaticPropsContext
-) => {
-  const { locale } = context;
-  const translation = await loadTranslation(locale);
-  const recentPosts = await getPublishedPosts({ first: 3 });
-
-  return {
-    props: {
-      recentPosts,
-      translation,
-    },
-  };
-};
-
-export default Home;
diff --git a/src/pages/mentions-legales.tsx b/src/pages/mentions-legales.tsx
deleted file mode 100644
index b103b5e..0000000
--- a/src/pages/mentions-legales.tsx
+++ /dev/null
@@ -1,150 +0,0 @@
-import { getLayout } from '@components/Layouts/Layout';
-import { Link } from '@components/MDX';
-import PostHeader from '@components/PostHeader/PostHeader';
-import Sidebar from '@components/Sidebar/Sidebar';
-import { ToC } from '@components/Widgets';
-import LegalNoticeContent, {
-  intro,
-  meta,
-} from '@content/pages/legal-notice.mdx';
-import styles from '@styles/pages/Page.module.scss';
-import { NextPageWithLayout } from '@ts/types/app';
-import { ArticleMeta } from '@ts/types/articles';
-import { settings } from '@utils/config';
-import { loadTranslation } from '@utils/helpers/i18n';
-import { NestedMDXComponents } from 'mdx/types';
-import { GetStaticProps, GetStaticPropsContext } from 'next';
-import Head from 'next/head';
-import { useRouter } from 'next/router';
-import Script from 'next/script';
-import { useIntl } from 'react-intl';
-import { Article, Graph, WebPage } from 'schema-dts';
-
-const LegalNotice: NextPageWithLayout = () => {
-  const intl = useIntl();
-  const router = useRouter();
-  const dates = {
-    publication: meta.publishedOn,
-    update: meta.updatedOn,
-  };
-
-  const pageMeta: ArticleMeta = {
-    dates,
-  };
-  const pageTitle = intl.formatMessage(
-    {
-      defaultMessage: 'Legal notice - {websiteName}',
-      description: 'LegalNoticePage: SEO - Page title',
-      id: '4zAUSu',
-    },
-    { websiteName: settings.name }
-  );
-  const pageDescription = intl.formatMessage(
-    {
-      defaultMessage: "Discover the legal notice of {websiteName}'s website.",
-      description: 'LegalNoticePage: SEO - Meta description',
-      id: 'uvB+32',
-    },
-    { websiteName: settings.name }
-  );
-  const pageUrl = `${settings.url}${router.asPath}`;
-  const title = intl.formatMessage({
-    defaultMessage: 'Legal notice',
-    description: 'LegalNoticePage: page title',
-    id: '/IirIt',
-  });
-  const publicationDate = new Date(dates.publication);
-  const updateDate = new Date(dates.update);
-
-  const webpageSchema: WebPage = {
-    '@id': `${pageUrl}`,
-    '@type': 'WebPage',
-    breadcrumb: { '@id': `${settings.url}/#breadcrumb` },
-    name: pageTitle,
-    description: pageDescription,
-    inLanguage: settings.locales.defaultLocale,
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-    reviewedBy: { '@id': `${settings.url}/#branding` },
-    url: `${pageUrl}`,
-    isPartOf: {
-      '@id': `${settings.url}`,
-    },
-  };
-
-  const articleSchema: Article = {
-    '@id': `${settings.url}/#legal-notice`,
-    '@type': 'Article',
-    name: title,
-    description: intro,
-    author: { '@id': `${settings.url}/#branding` },
-    copyrightYear: publicationDate.getFullYear(),
-    creator: { '@id': `${settings.url}/#branding` },
-    dateCreated: publicationDate.toISOString(),
-    dateModified: updateDate.toISOString(),
-    datePublished: publicationDate.toISOString(),
-    editor: { '@id': `${settings.url}/#branding` },
-    headline: title,
-    inLanguage: settings.locales.defaultLocale,
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-    mainEntityOfPage: { '@id': `${pageUrl}` },
-  };
-
-  const schemaJsonLd: Graph = {
-    '@context': 'https://schema.org',
-    '@graph': [webpageSchema, articleSchema],
-  };
-
-  const components: NestedMDXComponents = {
-    Link: (props) => Link(props),
-  };
-
-  return (
-    <>
-      <Head>
-        <title>{pageTitle}</title>
-        <meta name="description" content={pageDescription} />
-        <meta property="og:url" content={`${pageUrl}`} />
-        <meta property="og:type" content="article" />
-        <meta property="og:title" content={pageTitle} />
-        <meta property="og:description" content={intro} />
-      </Head>
-      <Script
-        id="schema-legal-notice"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      <article
-        id="legal-notice"
-        className={`${styles.article} ${styles['article--no-comments']}`}
-      >
-        <PostHeader intro={intro} meta={pageMeta} title={meta.title} />
-        <Sidebar position="left">
-          <ToC />
-        </Sidebar>
-        <div className={styles.body}>
-          <LegalNoticeContent components={components} />
-        </div>
-      </article>
-    </>
-  );
-};
-
-LegalNotice.getLayout = getLayout;
-
-export const getStaticProps: GetStaticProps = async (
-  context: GetStaticPropsContext
-) => {
-  const breadcrumbTitle = meta.title;
-  const { locale } = context;
-  const translation = await loadTranslation(locale);
-
-  return {
-    props: {
-      breadcrumbTitle,
-      locale,
-      translation,
-    },
-  };
-};
-
-export default LegalNotice;
diff --git a/src/pages/projet/[slug].tsx b/src/pages/projet/[slug].tsx
deleted file mode 100644
index 1f09fed..0000000
--- a/src/pages/projet/[slug].tsx
+++ /dev/null
@@ -1,186 +0,0 @@
-import { getLayout } from '@components/Layouts/Layout';
-import { CodeBlock, Gallery, Link, ResponsiveImage } from '@components/MDX';
-import PostHeader from '@components/PostHeader/PostHeader';
-import ProjectSummary from '@components/ProjectSummary/ProjectSummary';
-import Sidebar from '@components/Sidebar/Sidebar';
-import { Sharing, ToC } from '@components/Widgets';
-import styles from '@styles/pages/Page.module.scss';
-import {
-  NextPageWithLayout,
-  Project as ProjectData,
-  ProjectProps,
-} from '@ts/types/app';
-import { settings } from '@utils/config';
-import { loadTranslation } from '@utils/helpers/i18n';
-import {
-  getAllProjectsFilename,
-  getProjectData,
-} from '@utils/helpers/projects';
-import { MDXComponents, NestedMDXComponents } from 'mdx/types';
-import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from 'next';
-import Head from 'next/head';
-import { useRouter } from 'next/router';
-import Script from 'next/script';
-import { ParsedUrlQuery } from 'querystring';
-import { ComponentType } from 'react';
-import { useIntl } from 'react-intl';
-import { Article, Graph, WebPage } from 'schema-dts';
-
-const Project: NextPageWithLayout<ProjectProps> = ({
-  project,
-}: {
-  project: ProjectData;
-}) => {
-  const intl = useIntl();
-  const router = useRouter();
-  const projectUrl = `${settings.url}${router.asPath}`;
-  const { id, intro, meta, title, seo } = project;
-  const dates = {
-    publication: meta.publishedOn,
-    update: meta.updatedOn,
-  };
-
-  const components: NestedMDXComponents = {
-    CodeBlock: (props) => CodeBlock(props),
-    Gallery: (props) => Gallery(props),
-    Image: (props) => ResponsiveImage({ caption: props.caption, ...props }),
-    Link: (props) => Link(props),
-    pre: ({ children }) => CodeBlock(children.props),
-  };
-
-  const ProjectContent: ComponentType<MDXComponents> =
-    require(`../../content/projects/${id}.mdx`).default;
-
-  const webpageSchema: WebPage = {
-    '@id': `${projectUrl}`,
-    '@type': 'WebPage',
-    breadcrumb: { '@id': `${settings.url}/#breadcrumb` },
-    name: seo.title,
-    description: seo.description,
-    inLanguage: settings.locales.defaultLocale,
-    reviewedBy: { '@id': `${settings.url}/#branding` },
-    url: `${settings.url}`,
-    isPartOf: {
-      '@id': `${settings.url}`,
-    },
-  };
-
-  const publicationDate = new Date(dates.publication);
-  const updateDate = new Date(dates.update);
-
-  const articleSchema: Article = {
-    '@id': `${settings.url}/project`,
-    '@type': 'Article',
-    name: title,
-    description: intro,
-    author: { '@id': `${settings.url}/#branding` },
-    copyrightYear: publicationDate.getFullYear(),
-    creator: { '@id': `${settings.url}/#branding` },
-    dateCreated: publicationDate.toISOString(),
-    dateModified: updateDate.toISOString(),
-    datePublished: publicationDate.toISOString(),
-    editor: { '@id': `${settings.url}/#branding` },
-    headline: title,
-    thumbnailUrl: meta.hasCover ? `/projects/${id}.jpg` : '',
-    image: meta.hasCover ? `/projects/${id}.jpg` : '',
-    inLanguage: settings.locales.defaultLocale,
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-    mainEntityOfPage: { '@id': `${projectUrl}` },
-  };
-
-  const schemaJsonLd: Graph = {
-    '@context': 'https://schema.org',
-    '@graph': [webpageSchema, articleSchema],
-  };
-
-  return (
-    <>
-      <Head>
-        <title>{seo.title}</title>
-        <meta name="description" content={seo.description} />
-        <meta property="og:url" content={`${projectUrl}`} />
-        <meta property="og:type" content="article" />
-        <meta property="og:title" content={title} />
-        <meta property="og:description" content={intro} />
-      </Head>
-      <Script
-        id="schema-project"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      <article
-        id="project"
-        className={`${styles.article} ${styles['article--no-comments']}`}
-      >
-        <PostHeader title={title} intro={intro} meta={{ dates }} />
-        <Sidebar
-          position="left"
-          ariaLabel={intl.formatMessage({
-            defaultMessage: 'Table of Contents',
-            description: 'ProjectPage: ToC sidebar aria-label',
-            id: '6dXfvr',
-          })}
-        >
-          <ToC />
-        </Sidebar>
-        <div className={styles.body}>
-          <ProjectSummary id={id} title={title} meta={meta} />
-          <ProjectContent components={components} />
-        </div>
-        <Sidebar
-          position="right"
-          ariaLabel={intl.formatMessage({
-            defaultMessage: 'Sidebar',
-            description: 'ProjectPage: right sidebar aria-label',
-            id: 'hHrNd0',
-          })}
-        >
-          <Sharing title={title} excerpt={intro} />
-        </Sidebar>
-      </article>
-    </>
-  );
-};
-
-Project.getLayout = getLayout;
-
-interface ProjectParams extends ParsedUrlQuery {
-  slug: string;
-}
-
-export const getStaticProps: GetStaticProps = async (
-  context: GetStaticPropsContext
-) => {
-  const { locale } = context;
-  const translation = await loadTranslation(locale);
-  const { slug } = context.params as ProjectParams;
-  const project = await getProjectData(slug);
-  const breadcrumbTitle = project.title;
-
-  return {
-    props: {
-      breadcrumbTitle,
-      locale,
-      project,
-      translation,
-    },
-  };
-};
-
-export const getStaticPaths: GetStaticPaths = async () => {
-  const filenames = getAllProjectsFilename();
-  const paths = filenames.map((filename) => {
-    return {
-      params: {
-        slug: filename,
-      },
-    };
-  });
-
-  return {
-    paths,
-    fallback: false,
-  };
-};
-
-export default Project;
diff --git a/src/pages/projets.tsx b/src/pages/projets.tsx
deleted file mode 100644
index 8a81f39..0000000
--- a/src/pages/projets.tsx
+++ /dev/null
@@ -1,128 +0,0 @@
-import { getLayout } from '@components/Layouts/Layout';
-import PostHeader from '@components/PostHeader/PostHeader';
-import ProjectsList from '@components/ProjectsList/ProjectsList';
-import PageContent, { meta } from '@content/pages/projects.mdx';
-import styles from '@styles/pages/Projects.module.scss';
-import { Project } from '@ts/types/app';
-import { settings } from '@utils/config';
-import { loadTranslation } from '@utils/helpers/i18n';
-import { getSortedProjects } from '@utils/helpers/projects';
-import { GetStaticProps, GetStaticPropsContext } from 'next';
-import Head from 'next/head';
-import { useRouter } from 'next/router';
-import Script from 'next/script';
-import { useIntl } from 'react-intl';
-import { Article, Graph, WebPage } from 'schema-dts';
-
-const Projects = ({ projects }: { projects: Project[] }) => {
-  const intl = useIntl();
-  const dates = {
-    publication: meta.publishedOn,
-    update: meta.updatedOn,
-  };
-  const publicationDate = new Date(dates.publication);
-  const updateDate = new Date(dates.update);
-  const router = useRouter();
-  const pageUrl = `${settings.url}${router.asPath}`;
-  const pageTitle = intl.formatMessage(
-    {
-      defaultMessage: 'Projects: open-source makings - {websiteName}',
-      description: 'ProjectsPage: SEO - Page title',
-      id: 'SX1z3t',
-    },
-    { websiteName: settings.name }
-  );
-  const pageDescription = intl.formatMessage(
-    {
-      defaultMessage:
-        'Discover {websiteName} projects. Mostly related to web development and open source.',
-      description: 'ProjectsPage: SEO - Meta description',
-      id: 's6U1Xt',
-    },
-    { websiteName: settings.name }
-  );
-
-  const webpageSchema: WebPage = {
-    '@id': `${pageUrl}`,
-    '@type': 'WebPage',
-    breadcrumb: { '@id': `${settings.url}/#breadcrumb` },
-    name: pageTitle,
-    description: pageDescription,
-    inLanguage: settings.locales.defaultLocale,
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-    reviewedBy: { '@id': `${settings.url}/#branding` },
-    url: `${pageUrl}`,
-    isPartOf: {
-      '@id': `${settings.url}`,
-    },
-  };
-
-  const articleSchema: Article = {
-    '@id': `${settings.url}/#projects`,
-    '@type': 'Article',
-    name: meta.title,
-    description: pageDescription,
-    author: { '@id': `${settings.url}/#branding` },
-    copyrightYear: publicationDate.getFullYear(),
-    creator: { '@id': `${settings.url}/#branding` },
-    dateCreated: publicationDate.toISOString(),
-    dateModified: updateDate.toISOString(),
-    datePublished: publicationDate.toISOString(),
-    editor: { '@id': `${settings.url}/#branding` },
-    headline: meta.title,
-    inLanguage: settings.locales.defaultLocale,
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-    mainEntityOfPage: { '@id': `${pageUrl}` },
-  };
-
-  const schemaJsonLd: Graph = {
-    '@context': 'https://schema.org',
-    '@graph': [webpageSchema, articleSchema],
-  };
-
-  return (
-    <>
-      <Head>
-        <title>{pageTitle}</title>
-        <meta name="description" content={pageDescription} />
-        <meta property="og:url" content={`${pageUrl}`} />
-        <meta property="og:type" content="article" />
-        <meta property="og:title" content={meta.title} />
-        <meta property="og:description" content={pageDescription} />
-      </Head>
-      <Script
-        id="schema-projects"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      <article id="projects" className={styles.article}>
-        <PostHeader title={meta.title} intro={<PageContent />} />
-        <div className={styles.body}>
-          {projects.length > 0 && <ProjectsList projects={projects} />}
-        </div>
-      </article>
-    </>
-  );
-};
-
-Projects.getLayout = getLayout;
-
-export const getStaticProps: GetStaticProps = async (
-  context: GetStaticPropsContext
-) => {
-  const breadcrumbTitle = meta.title;
-  const { locale } = context;
-  const projects: Project[] = await getSortedProjects();
-  const translation = await loadTranslation(locale);
-
-  return {
-    props: {
-      breadcrumbTitle,
-      locale,
-      projects,
-      translation,
-    },
-  };
-};
-
-export default Projects;
diff --git a/src/pages/recherche/index.tsx b/src/pages/recherche/index.tsx
deleted file mode 100644
index b843f8d..0000000
--- a/src/pages/recherche/index.tsx
+++ /dev/null
@@ -1,213 +0,0 @@
-import { Button } from '@components/Buttons';
-import { getLayout } from '@components/Layouts/Layout';
-import PaginationCursor from '@components/PaginationCursor/PaginationCursor';
-import PostHeader from '@components/PostHeader/PostHeader';
-import PostsList from '@components/PostsList/PostsList';
-import Sidebar from '@components/Sidebar/Sidebar';
-import Spinner from '@components/Spinner/Spinner';
-import { ThematicsList, TopicsList } from '@components/Widgets';
-import { getPublishedPosts } from '@services/graphql/queries';
-import styles from '@styles/pages/Page.module.scss';
-import { NextPageWithLayout } from '@ts/types/app';
-import { PostsList as PostsListData } from '@ts/types/blog';
-import { settings } from '@utils/config';
-import { getIntlInstance, loadTranslation } from '@utils/helpers/i18n';
-import { GetStaticProps, GetStaticPropsContext } from 'next';
-import Head from 'next/head';
-import { useRouter } from 'next/router';
-import { useEffect, useRef, useState } from 'react';
-import { useIntl } from 'react-intl';
-import useSWRInfinite from 'swr/infinite';
-
-const Search: NextPageWithLayout = () => {
-  const intl = useIntl();
-  const [query, setQuery] = useState('');
-  const router = useRouter();
-  const lastPostRef = useRef<HTMLSpanElement>(null);
-
-  useEffect(() => {
-    if (!router.isReady) return;
-
-    if (router.query?.s && typeof router.query.s === 'string') {
-      setQuery(router.query.s);
-    }
-  }, [router.isReady, router.query.s]);
-
-  const getKey = (pageIndex: number, previousData: PostsListData) => {
-    if (previousData && !previousData.posts) return null;
-
-    return pageIndex === 0
-      ? { first: settings.postsPerPage, searchQuery: query }
-      : {
-          first: settings.postsPerPage,
-          after: previousData.pageInfo.endCursor,
-          searchQuery: query,
-        };
-  };
-
-  const { data, error, size, setSize } = useSWRInfinite(
-    getKey,
-    getPublishedPosts
-  );
-  const [totalPostsCount, setTotalPostsCount] = useState<number>(0);
-
-  useEffect(() => {
-    if (data) setTotalPostsCount(data[0].pageInfo.total);
-  }, [data]);
-
-  const [loadedPostsCount, setLoadedPostsCount] = useState<number>(
-    settings.postsPerPage
-  );
-
-  useEffect(() => {
-    if (data && data.length > 0) {
-      const newCount =
-        settings.postsPerPage +
-        data[0].pageInfo.total -
-        data[data.length - 1].pageInfo.total;
-      setLoadedPostsCount(newCount);
-    }
-  }, [data]);
-
-  const isLoadingInitialData = !data && !error;
-  const isLoadingMore: boolean =
-    isLoadingInitialData ||
-    (size > 0 && data !== undefined && typeof data[size - 1] === 'undefined');
-
-  const hasNextPage = data && data[data.length - 1].pageInfo.hasNextPage;
-
-  const title = query
-    ? intl.formatMessage(
-        {
-          defaultMessage: 'Search results for {query}',
-          description: 'SearchPage: search results text',
-          id: 'VSGuGE',
-        },
-        { query }
-      )
-    : intl.formatMessage({
-        defaultMessage: 'Search',
-        description: 'SearchPage: page title',
-        id: 'U+35YD',
-      });
-
-  const description = query
-    ? intl.formatMessage(
-        {
-          defaultMessage: 'Discover search results for {query}',
-          description: 'SearchPage: meta description with query',
-          id: 'A4LTGq',
-        },
-        { query }
-      )
-    : intl.formatMessage(
-        {
-          defaultMessage: 'Search for a post on {websiteName}',
-          description: 'SearchPage: meta description without query',
-          id: 'PrIz5o',
-        },
-        { websiteName: settings.name }
-      );
-
-  const head = {
-    title: `${title} | ${settings.name}`,
-    description,
-  };
-
-  const loadMorePosts = () => {
-    if (lastPostRef.current) {
-      lastPostRef.current.focus();
-    }
-    setSize(size + 1);
-  };
-
-  const getPostsList = () => {
-    if (error)
-      return intl.formatMessage({
-        defaultMessage: 'Failed to load.',
-        description: 'SearchPage: failed to load text',
-        id: 'fOe8rH',
-      });
-    if (!data) return <Spinner />;
-
-    return <PostsList ref={lastPostRef} data={data} showYears={false} />;
-  };
-
-  return (
-    <>
-      <Head>
-        <title>{head.title}</title>
-        <meta name="description" content={head.description} />
-      </Head>
-      <article
-        className={`${styles.article} ${styles['article--no-comments']}`}
-      >
-        <PostHeader title={title} meta={{ results: totalPostsCount }} />
-        <div className={styles.body}>
-          {getPostsList()}
-          {hasNextPage && (
-            <>
-              <PaginationCursor
-                current={loadedPostsCount}
-                total={totalPostsCount}
-              />
-              <Button
-                isDisabled={isLoadingMore}
-                clickHandler={loadMorePosts}
-                position="center"
-                spacing={true}
-              >
-                {intl.formatMessage({
-                  defaultMessage: 'Load more?',
-                  description: 'SearchPage: load more text',
-                  id: 'pEtJik',
-                })}
-              </Button>
-            </>
-          )}
-        </div>
-        <Sidebar position="right">
-          <ThematicsList
-            title={intl.formatMessage({
-              defaultMessage: 'Thematics',
-              description: 'SearchPage: thematics list widget title',
-              id: 'Dq6+WH',
-            })}
-          />
-          <TopicsList
-            title={intl.formatMessage({
-              defaultMessage: 'Topics',
-              description: 'SearchPage: topics list widget title',
-              id: 'N804XO',
-            })}
-          />
-        </Sidebar>
-      </article>
-    </>
-  );
-};
-
-Search.getLayout = getLayout;
-
-export const getStaticProps: GetStaticProps = async (
-  context: GetStaticPropsContext
-) => {
-  const intl = await getIntlInstance();
-  const breadcrumbTitle = intl.formatMessage({
-    defaultMessage: 'Search',
-    description: 'SearchPage: breadcrumb item',
-    id: 'TfU6Qm',
-  });
-  const { locale } = context;
-  const translation = await loadTranslation(locale);
-
-  return {
-    props: {
-      breadcrumbTitle,
-      locale,
-      translation,
-    },
-  };
-};
-
-export default Search;
diff --git a/src/pages/sujet/[slug].tsx b/src/pages/sujet/[slug].tsx
deleted file mode 100644
index 30dd36c..0000000
--- a/src/pages/sujet/[slug].tsx
+++ /dev/null
@@ -1,224 +0,0 @@
-import { getLayout } from '@components/Layouts/Layout';
-import PostHeader from '@components/PostHeader/PostHeader';
-import PostPreview from '@components/PostPreview/PostPreview';
-import Sidebar from '@components/Sidebar/Sidebar';
-import Spinner from '@components/Spinner/Spinner';
-import { RelatedThematics, ToC, TopicsList } from '@components/Widgets';
-import {
-  getAllTopics,
-  getAllTopicsSlug,
-  getTopicBySlug,
-} from '@services/graphql/queries';
-import styles from '@styles/pages/Page.module.scss';
-import { NextPageWithLayout } from '@ts/types/app';
-import { ArticleMeta } from '@ts/types/articles';
-import { TopicProps, ThematicPreview } from '@ts/types/taxonomies';
-import { settings } from '@utils/config';
-import { getFormattedPaths } from '@utils/helpers/format';
-import { loadTranslation } from '@utils/helpers/i18n';
-import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from 'next';
-import Head from 'next/head';
-import { useRouter } from 'next/router';
-import Script from 'next/script';
-import { ParsedUrlQuery } from 'querystring';
-import { useRef } from 'react';
-import { useIntl } from 'react-intl';
-import { Article as Article, Graph, WebPage } from 'schema-dts';
-
-const Topic: NextPageWithLayout<TopicProps> = ({ topic, allTopics }) => {
-  const intl = useIntl();
-  const relatedThematics = useRef<ThematicPreview[]>([]);
-  const router = useRouter();
-
-  if (router.isFallback) return <Spinner />;
-
-  const updateRelatedThematics = (newThematics: ThematicPreview[]) => {
-    newThematics.forEach((thematic) => {
-      const thematicIndex = relatedThematics.current.findIndex(
-        (relatedThematic) => relatedThematic.id === thematic.id
-      );
-      const hasThematic = thematicIndex === -1 ? false : true;
-
-      if (!hasThematic) relatedThematics.current.push(thematic);
-    });
-  };
-
-  const getPostsList = () => {
-    return [...topic.posts].reverse().map((post) => {
-      updateRelatedThematics(post.thematics);
-
-      return (
-        <li key={post.id} className={styles.item}>
-          <PostPreview post={post} titleLevel={3} />
-        </li>
-      );
-    });
-  };
-
-  const meta: ArticleMeta = {
-    dates: topic.dates,
-    results: topic.posts.length,
-    website: topic.officialWebsite,
-  };
-  const topicUrl = `${settings.url}${router.asPath}`;
-
-  const webpageSchema: WebPage = {
-    '@id': `${topicUrl}`,
-    '@type': 'WebPage',
-    breadcrumb: { '@id': `${settings.url}/#breadcrumb` },
-    name: topic.seo.title,
-    description: topic.seo.metaDesc,
-    inLanguage: settings.locales.defaultLocale,
-    reviewedBy: { '@id': `${settings.url}/#branding` },
-    url: `${settings.url}`,
-    isPartOf: {
-      '@id': `${settings.url}`,
-    },
-  };
-
-  const publicationDate = new Date(topic.dates.publication);
-  const updateDate = new Date(topic.dates.update);
-
-  const articleSchema: Article = {
-    '@id': `${settings.url}/#topic`,
-    '@type': 'Article',
-    name: topic.title,
-    description: topic.intro,
-    author: { '@id': `${settings.url}/#branding` },
-    copyrightYear: publicationDate.getFullYear(),
-    creator: { '@id': `${settings.url}/#branding` },
-    dateCreated: publicationDate.toISOString(),
-    dateModified: updateDate.toISOString(),
-    datePublished: publicationDate.toISOString(),
-    editor: { '@id': `${settings.url}/#branding` },
-    headline: topic.title,
-    thumbnailUrl: topic.featuredImage?.sourceUrl,
-    image: topic.featuredImage?.sourceUrl,
-    inLanguage: settings.locales.defaultLocale,
-    isPartOf: { '@id': `${settings.url}/blog` },
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-    mainEntityOfPage: { '@id': `${topicUrl}` },
-    subjectOf: { '@id': `${settings.url}/blog` },
-  };
-
-  const schemaJsonLd: Graph = {
-    '@context': 'https://schema.org',
-    '@graph': [webpageSchema, articleSchema],
-  };
-
-  return (
-    <>
-      <Head>
-        <title>{topic.seo.title}</title>
-        <meta name="description" content={topic.seo.metaDesc} />
-        <meta property="og:url" content={`${topicUrl}`} />
-        <meta property="og:type" content="article" />
-        <meta property="og:title" content={topic.title} />
-        <meta property="og:description" content={topic.intro} />
-        <meta property="og:image" content={topic.featuredImage?.sourceUrl} />
-        <meta property="og:image:alt" content={topic.featuredImage?.altText} />
-      </Head>
-      <Script
-        id="schema-subject"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      <article
-        id="topic"
-        className={`${styles.article} ${styles['article--no-comments']}`}
-      >
-        <PostHeader
-          cover={topic.featuredImage}
-          intro={topic.intro}
-          meta={meta}
-          title={topic.title}
-        />
-        <Sidebar
-          position="left"
-          ariaLabel={intl.formatMessage({
-            defaultMessage: 'Table of Contents',
-            description: 'TopicPage: ToC sidebar aria-label',
-            id: 'lsDB5G',
-          })}
-        >
-          <ToC />
-        </Sidebar>
-        <div className={styles.body}>
-          <div dangerouslySetInnerHTML={{ __html: topic.content }}></div>
-          {topic.posts.length > 0 && (
-            <section className={styles.section}>
-              <h2>
-                {intl.formatMessage(
-                  {
-                    defaultMessage: 'All posts in {name}',
-                    description: 'TopicPage: posts list title',
-                    id: 'FLkF2R',
-                  },
-                  { name: topic.title }
-                )}
-              </h2>
-              <ol className={styles.list}>{getPostsList()}</ol>
-            </section>
-          )}
-        </div>
-        <Sidebar
-          position="right"
-          ariaLabel={intl.formatMessage({
-            defaultMessage: 'Sidebar',
-            description: 'TopicPage: right sidebar aria-label',
-            id: 'eu3beS',
-          })}
-        >
-          <RelatedThematics thematics={relatedThematics.current} />
-          <TopicsList
-            initialData={allTopics}
-            title={intl.formatMessage({
-              defaultMessage: 'Others topics',
-              description: 'TopicPage: topics list widget title',
-              id: '+4tiVb',
-            })}
-          />
-        </Sidebar>
-      </article>
-    </>
-  );
-};
-
-Topic.getLayout = getLayout;
-
-interface PostParams extends ParsedUrlQuery {
-  slug: string;
-}
-
-export const getStaticProps: GetStaticProps = async (
-  context: GetStaticPropsContext
-) => {
-  const { locale } = context;
-  const translation = await loadTranslation(locale);
-  const { slug } = context.params as PostParams;
-  const topic = await getTopicBySlug(slug);
-  const allTopics = await getAllTopics();
-  const breadcrumbTitle = topic.title;
-
-  return {
-    props: {
-      allTopics,
-      breadcrumbTitle,
-      locale,
-      topic,
-      translation,
-    },
-  };
-};
-
-export const getStaticPaths: GetStaticPaths = async () => {
-  const allTopics = await getAllTopicsSlug();
-  const paths = getFormattedPaths(allTopics);
-
-  return {
-    paths,
-    fallback: true,
-  };
-};
-
-export default Topic;
diff --git a/src/pages/thematique/[slug].tsx b/src/pages/thematique/[slug].tsx
deleted file mode 100644
index db22214..0000000
--- a/src/pages/thematique/[slug].tsx
+++ /dev/null
@@ -1,214 +0,0 @@
-import { getLayout } from '@components/Layouts/Layout';
-import PostHeader from '@components/PostHeader/PostHeader';
-import PostPreview from '@components/PostPreview/PostPreview';
-import Sidebar from '@components/Sidebar/Sidebar';
-import Spinner from '@components/Spinner/Spinner';
-import { RelatedTopics, ThematicsList, ToC } from '@components/Widgets';
-import {
-  getAllThematics,
-  getAllThematicsSlug,
-  getThematicBySlug,
-} from '@services/graphql/queries';
-import styles from '@styles/pages/Page.module.scss';
-import { NextPageWithLayout } from '@ts/types/app';
-import { ArticleMeta } from '@ts/types/articles';
-import { TopicPreview, ThematicProps } from '@ts/types/taxonomies';
-import { settings } from '@utils/config';
-import { getFormattedPaths } from '@utils/helpers/format';
-import { loadTranslation } from '@utils/helpers/i18n';
-import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from 'next';
-import Head from 'next/head';
-import { useRouter } from 'next/router';
-import Script from 'next/script';
-import { ParsedUrlQuery } from 'querystring';
-import { useRef } from 'react';
-import { useIntl } from 'react-intl';
-import { Article, Graph, WebPage } from 'schema-dts';
-
-const Thematic: NextPageWithLayout<ThematicProps> = ({
-  thematic,
-  allThematics,
-}) => {
-  const intl = useIntl();
-  const relatedTopics = useRef<TopicPreview[]>([]);
-  const router = useRouter();
-
-  if (router.isFallback) return <Spinner />;
-
-  const updateRelatedTopics = (newTopics: TopicPreview[]) => {
-    newTopics.forEach((topic) => {
-      const topicIndex = relatedTopics.current.findIndex(
-        (relatedTopic) => relatedTopic.id === topic.id
-      );
-      const hasTopic = topicIndex === -1 ? false : true;
-
-      if (!hasTopic) relatedTopics.current.push(topic);
-    });
-  };
-
-  const getPostsList = () => {
-    return [...thematic.posts].reverse().map((post) => {
-      updateRelatedTopics(post.topics);
-
-      return (
-        <li key={post.id} className={styles.item}>
-          <PostPreview post={post} titleLevel={3} />
-        </li>
-      );
-    });
-  };
-
-  const meta: ArticleMeta = {
-    dates: thematic.dates,
-    results: thematic.posts.length,
-  };
-  const thematicUrl = `${settings.url}${router.asPath}`;
-
-  const webpageSchema: WebPage = {
-    '@id': `${thematicUrl}`,
-    '@type': 'WebPage',
-    breadcrumb: { '@id': `${settings.url}/#breadcrumb` },
-    name: thematic.seo.title,
-    description: thematic.seo.metaDesc,
-    inLanguage: settings.locales.defaultLocale,
-    reviewedBy: { '@id': `${settings.url}/#branding` },
-    url: `${settings.url}`,
-  };
-
-  const publicationDate = new Date(thematic.dates.publication);
-  const updateDate = new Date(thematic.dates.update);
-
-  const articleSchema: Article = {
-    '@id': `${settings.url}/#thematic`,
-    '@type': 'Article',
-    name: thematic.title,
-    description: thematic.intro,
-    author: { '@id': `${settings.url}/#branding` },
-    copyrightYear: publicationDate.getFullYear(),
-    creator: { '@id': `${settings.url}/#branding` },
-    dateCreated: publicationDate.toISOString(),
-    dateModified: updateDate.toISOString(),
-    datePublished: publicationDate.toISOString(),
-    editor: { '@id': `${settings.url}/#branding` },
-    headline: thematic.title,
-    inLanguage: settings.locales.defaultLocale,
-    isPartOf: { '@id': `${settings.url}/blog` },
-    license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr',
-    mainEntityOfPage: { '@id': `${thematicUrl}` },
-    subjectOf: { '@id': `${settings.url}/blog` },
-  };
-
-  const schemaJsonLd: Graph = {
-    '@context': 'https://schema.org',
-    '@graph': [webpageSchema, articleSchema],
-  };
-
-  return (
-    <>
-      <Head>
-        <title>{thematic.seo.title}</title>
-        <meta name="description" content={thematic.seo.metaDesc} />
-        <meta property="og:url" content={`${thematic}`} />
-        <meta property="og:type" content="article" />
-        <meta property="og:title" content={thematic.title} />
-        <meta property="og:description" content={thematic.intro} />
-      </Head>
-      <Script
-        id="schema-thematic"
-        type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
-      />
-      <article
-        id="thematic"
-        className={`${styles.article} ${styles['article--no-comments']}`}
-      >
-        <PostHeader intro={thematic.intro} meta={meta} title={thematic.title} />
-        <Sidebar
-          position="left"
-          ariaLabel={intl.formatMessage({
-            defaultMessage: 'Table of Contents',
-            description: 'ThematicPage: ToC sidebar aria-label',
-            id: 'YwvYfw',
-          })}
-        >
-          <ToC />
-        </Sidebar>
-        <div className={styles.body}>
-          <div dangerouslySetInnerHTML={{ __html: thematic.content }}></div>
-          {thematic.posts.length > 0 && (
-            <section className={styles.section}>
-              <h2>
-                {intl.formatMessage(
-                  {
-                    defaultMessage: 'All posts in {name}',
-                    description: 'ThematicPage: posts list title',
-                    id: 'P7fxX2',
-                  },
-                  { name: thematic.title }
-                )}
-              </h2>
-              <ol className={styles.list}>{getPostsList()}</ol>
-            </section>
-          )}
-        </div>
-        <Sidebar
-          position="right"
-          ariaLabel={intl.formatMessage({
-            defaultMessage: 'Sidebar',
-            description: 'ThematicPage: right sidebar aria-label',
-            id: 'syLgY9',
-          })}
-        >
-          <RelatedTopics topics={relatedTopics.current} />
-          <ThematicsList
-            initialData={allThematics}
-            title={intl.formatMessage({
-              defaultMessage: 'Others thematics',
-              description: 'ThematicPage: thematics list widget title',
-              id: 'norrGp',
-            })}
-          />
-        </Sidebar>
-      </article>
-    </>
-  );
-};
-
-Thematic.getLayout = getLayout;
-
-interface PostParams extends ParsedUrlQuery {
-  slug: string;
-}
-
-export const getStaticProps: GetStaticProps = async (
-  context: GetStaticPropsContext
-) => {
-  const { locale } = context;
-  const translation = await loadTranslation(locale);
-  const { slug } = context.params as PostParams;
-  const thematic = await getThematicBySlug(slug);
-  const allThematics = await getAllThematics();
-  const breadcrumbTitle = thematic.title;
-
-  return {
-    props: {
-      allThematics,
-      breadcrumbTitle,
-      locale,
-      thematic,
-      translation,
-    },
-  };
-};
-
-export const getStaticPaths: GetStaticPaths = async () => {
-  const allSlugs = await getAllThematicsSlug();
-  const paths = getFormattedPaths(allSlugs);
-
-  return {
-    paths,
-    fallback: true,
-  };
-};
-
-export default Thematic;
diff --git a/src/services/graphql/api.ts b/src/services/graphql/api.ts
deleted file mode 100644
index a5be026..0000000
--- a/src/services/graphql/api.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { RequestType, VariablesType } from '@ts/types/app';
-import { settings } from '@utils/config';
-import { GraphQLClient } from 'graphql-request';
-
-export const getGraphQLClient = (): GraphQLClient => {
-  const apiUrl = settings.api.url;
-
-  if (!apiUrl) throw new Error('API URL not defined.');
-
-  return new GraphQLClient(apiUrl);
-};
-
-export const fetchApi = async <T extends RequestType>(
-  query: string,
-  variables: VariablesType<T>
-): Promise<T> => {
-  const client = getGraphQLClient();
-
-  try {
-    return await client.request(query, variables);
-  } catch (error) {
-    console.error(error, undefined, 2);
-    process.exit(1);
-  }
-};
diff --git a/src/services/graphql/mutations.ts b/src/services/graphql/mutations.ts
deleted file mode 100644
index c697835..0000000
--- a/src/services/graphql/mutations.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import { CommentData, CreateComment, CreatedComment } from '@ts/types/comments';
-import { ContactData, SendEmail } from '@ts/types/contact';
-import { gql } from 'graphql-request';
-import { fetchApi } from './api';
-
-//==============================================================================
-// Comment mutation
-//==============================================================================
-
-export const createComment = async (
-  data: CommentData
-): Promise<CreatedComment> => {
-  const mutation = gql`
-    mutation CreateComment(
-      $author: String!
-      $authorEmail: String!
-      $authorUrl: String!
-      $content: String!
-      $parent: ID!
-      $commentOn: Int!
-      $mutationId: String!
-    ) {
-      createComment(
-        input: {
-          author: $author
-          authorEmail: $authorEmail
-          authorUrl: $authorUrl
-          content: $content
-          parent: $parent
-          commentOn: $commentOn
-          clientMutationId: $mutationId
-        }
-      ) {
-        clientMutationId
-        success
-        comment {
-          approved
-        }
-      }
-    }
-  `;
-
-  const variables = { ...data };
-  const response = await fetchApi<CreateComment>(mutation, variables);
-
-  return response.createComment;
-};
-
-//==============================================================================
-// Contact mutation
-//==============================================================================
-
-export const sendMail = async (data: ContactData) => {
-  const mutation = gql`
-    mutation SendEmail(
-      $subject: String!
-      $body: String!
-      $replyTo: String!
-      $mutationId: String!
-    ) {
-      sendEmail(
-        input: {
-          clientMutationId: $mutationId
-          body: $body
-          replyTo: $replyTo
-          subject: $subject
-        }
-      ) {
-        clientMutationId
-        message
-        sent
-        origin
-        replyTo
-        to
-      }
-    }
-  `;
-
-  const variables = { ...data };
-  const response = await fetchApi<SendEmail>(mutation, variables);
-  return response.sendEmail;
-};
diff --git a/src/services/graphql/queries.ts b/src/services/graphql/queries.ts
deleted file mode 100644
index 9caf62b..0000000
--- a/src/services/graphql/queries.ts
+++ /dev/null
@@ -1,535 +0,0 @@
-import { Slug } from '@ts/types/app';
-import { Article, PostBy, TotalArticles } from '@ts/types/articles';
-import {
-  AllPostsSlug,
-  LastPostCursor,
-  PostsList,
-  RawPostsList,
-} from '@ts/types/blog';
-import { Comment, CommentsByPostId } from '@ts/types/comments';
-import {
-  AllTopics,
-  AllTopicsSlug,
-  AllThematics,
-  AllThematicsSlug,
-  Topic,
-  TopicBy,
-  TopicPreview,
-  Thematic,
-  ThematicBy,
-  ThematicPreview,
-} from '@ts/types/taxonomies';
-import {
-  getFormattedPost,
-  getFormattedPostPreview,
-  getFormattedTopic,
-  getFormattedThematic,
-  getFormattedComments,
-  buildCommentsTree,
-} from '@utils/helpers/format';
-import { gql } from 'graphql-request';
-import { fetchApi } from './api';
-
-//==============================================================================
-// Posts list queries
-//==============================================================================
-
-export const getPostsTotal = async (): Promise<number> => {
-  const query = gql`
-    query PostsTotal {
-      posts {
-        pageInfo {
-          total
-        }
-      }
-    }
-  `;
-
-  const response = await fetchApi<TotalArticles>(query, null);
-  return response.posts.pageInfo.total;
-};
-
-export const getPublishedPosts = async ({
-  first = 10,
-  after = '',
-  searchQuery = '',
-}: {
-  first: number;
-  after?: string;
-  searchQuery?: string;
-}): Promise<PostsList> => {
-  const query = gql`
-    query AllPublishedPosts($first: Int, $after: String, $searchQuery: String) {
-      posts(
-        after: $after
-        first: $first
-        where: {
-          status: PUBLISH
-          orderby: { field: DATE, order: DESC }
-          search: $searchQuery
-        }
-      ) {
-        edges {
-          cursor
-          node {
-            acfPosts {
-              postsInTopic {
-                ... on Topic {
-                  databaseId
-                  featuredImage {
-                    node {
-                      altText
-                      sourceUrl
-                      title
-                    }
-                  }
-                  id
-                  slug
-                  title
-                }
-              }
-              postsInThematic {
-                ... on Thematic {
-                  databaseId
-                  id
-                  slug
-                  title
-                }
-              }
-            }
-            commentCount
-            contentParts {
-              beforeMore
-            }
-            date
-            featuredImage {
-              node {
-                altText
-                sourceUrl
-                title
-              }
-            }
-            id
-            info {
-              readingTime
-              wordsCount
-            }
-            databaseId
-            modified
-            slug
-            title
-          }
-        }
-        pageInfo {
-          endCursor
-          hasNextPage
-          total
-        }
-      }
-    }
-  `;
-
-  const variables = { first, after, searchQuery };
-  const response = await fetchApi<RawPostsList>(query, variables);
-  const formattedPosts = response.posts.edges.map((post) => {
-    return getFormattedPostPreview(post.node);
-  });
-
-  return {
-    posts: formattedPosts,
-    pageInfo: response.posts.pageInfo,
-  };
-};
-
-export const getAllPostsSlug = async (): Promise<Slug[]> => {
-  // 10 000 is an arbitrary number that I use for small websites.
-  const query = gql`
-    query AllPostsSlug {
-      posts(first: 10000) {
-        nodes {
-          slug
-        }
-      }
-    }
-  `;
-
-  const response = await fetchApi<AllPostsSlug>(query, null);
-  return response.posts.nodes;
-};
-
-//==============================================================================
-// Single Post query
-//==============================================================================
-
-export const getPostBySlug = async (slug: string): Promise<Article> => {
-  const query = gql`
-    query PostBySlug($slug: ID!) {
-      post(id: $slug, idType: SLUG) {
-        acfPosts {
-          postsInTopic {
-            ... on Topic {
-              id
-              featuredImage {
-                node {
-                  altText
-                  sourceUrl
-                  title
-                }
-              }
-              slug
-              title
-            }
-          }
-          postsInThematic {
-            ... on Thematic {
-              id
-              slug
-              title
-            }
-          }
-        }
-        author {
-          node {
-            firstName
-            lastName
-            name
-          }
-        }
-        commentCount
-        contentParts {
-          afterMore
-          beforeMore
-        }
-        databaseId
-        date
-        featuredImage {
-          node {
-            altText
-            sourceUrl
-            title
-          }
-        }
-        id
-        info {
-          readingTime
-          wordsCount
-        }
-        modified
-        seo {
-          metaDesc
-          title
-        }
-        title
-      }
-    }
-  `;
-  const variables = { slug };
-  const response = await fetchApi<PostBy>(query, variables);
-
-  return getFormattedPost(response.post);
-};
-
-//==============================================================================
-// Comments query
-//==============================================================================
-
-export const getCommentsByPostId = async (id: number): Promise<Comment[]> => {
-  const query = gql`
-    query PostComments($id: ID!) {
-      comments(where: { contentId: $id, order: ASC, orderby: COMMENT_DATE }) {
-        nodes {
-          approved
-          author {
-            node {
-              databaseId
-              gravatarUrl
-              name
-              url
-            }
-          }
-          content
-          databaseId
-          date
-          parentDatabaseId
-        }
-      }
-    }
-  `;
-
-  const variables = { id };
-  const response = await fetchApi<CommentsByPostId>(query, variables);
-  const formattedComments = getFormattedComments(response.comments.nodes);
-
-  return buildCommentsTree(formattedComments);
-};
-
-//==============================================================================
-// Topic query
-//==============================================================================
-
-export const getTopicBySlug = async (slug: string): Promise<Topic> => {
-  const query = gql`
-    query TopicBySlug($slug: ID!) {
-      topic(id: $slug, idType: SLUG) {
-        acfTopics {
-          officialWebsite
-          postsInTopic {
-            ... on Post {
-              acfPosts {
-                postsInTopic {
-                  ... on Topic {
-                    databaseId
-                    featuredImage {
-                      node {
-                        altText
-                        sourceUrl
-                        title
-                      }
-                    }
-                    id
-                    slug
-                    title
-                  }
-                }
-                postsInThematic {
-                  ... on Thematic {
-                    databaseId
-                    id
-                    slug
-                    title
-                  }
-                }
-              }
-              id
-              info {
-                readingTime
-                wordsCount
-              }
-              commentCount
-              contentParts {
-                beforeMore
-              }
-              databaseId
-              date
-              featuredImage {
-                node {
-                  altText
-                  sourceUrl
-                  title
-                }
-              }
-              modified
-              slug
-              title
-            }
-          }
-        }
-        contentParts {
-          afterMore
-          beforeMore
-        }
-        databaseId
-        date
-        featuredImage {
-          node {
-            altText
-            sourceUrl
-            title
-          }
-        }
-        id
-        info {
-          readingTime
-          wordsCount
-        }
-        modified
-        seo {
-          metaDesc
-          title
-        }
-        title
-      }
-    }
-  `;
-  const variables = { slug };
-  const response = await fetchApi<TopicBy>(query, variables);
-
-  return getFormattedTopic(response.topic);
-};
-
-export const getAllTopicsSlug = async (): Promise<Slug[]> => {
-  // 10 000 is an arbitrary number that I use for small websites.
-  const query = gql`
-    query AllTopicsSlug {
-      topics(first: 10000) {
-        nodes {
-          slug
-        }
-      }
-    }
-  `;
-  const response = await fetchApi<AllTopicsSlug>(query, null);
-  return response.topics.nodes;
-};
-
-export const getAllTopics = async (): Promise<TopicPreview[]> => {
-  // 10 000 is an arbitrary number that I use for small websites.
-  const query = gql`
-    query AllTopics {
-      topics(first: 10000, where: { orderby: { field: TITLE, order: ASC } }) {
-        nodes {
-          databaseId
-          slug
-          title
-        }
-      }
-    }
-  `;
-
-  const response = await fetchApi<AllTopics>(query, null);
-  return response.topics.nodes;
-};
-
-//==============================================================================
-// Thematic query
-//==============================================================================
-
-export const getThematicBySlug = async (slug: string): Promise<Thematic> => {
-  const query = gql`
-    query ThematicBySlug($slug: ID!) {
-      thematic(id: $slug, idType: SLUG) {
-        acfThematics {
-          postsInThematic {
-            ... on Post {
-              acfPosts {
-                postsInTopic {
-                  ... on Topic {
-                    databaseId
-                    featuredImage {
-                      node {
-                        altText
-                        sourceUrl
-                        title
-                      }
-                    }
-                    id
-                    slug
-                    title
-                  }
-                }
-                postsInThematic {
-                  ... on Thematic {
-                    databaseId
-                    id
-                    slug
-                    title
-                  }
-                }
-              }
-              id
-              info {
-                readingTime
-                wordsCount
-              }
-              commentCount
-              contentParts {
-                beforeMore
-              }
-              databaseId
-              date
-              featuredImage {
-                node {
-                  altText
-                  sourceUrl
-                  title
-                }
-              }
-              modified
-              slug
-              title
-            }
-          }
-        }
-        contentParts {
-          afterMore
-          beforeMore
-        }
-        databaseId
-        date
-        id
-        info {
-          readingTime
-          wordsCount
-        }
-        modified
-        seo {
-          metaDesc
-          title
-        }
-        title
-      }
-    }
-  `;
-  const variables = { slug };
-  const response = await fetchApi<ThematicBy>(query, variables);
-
-  return getFormattedThematic(response.thematic);
-};
-
-export const getAllThematicsSlug = async (): Promise<Slug[]> => {
-  // 10 000 is an arbitrary number that I use for small websites.
-  const query = gql`
-    query AllThematicsSlug {
-      thematics(first: 10000) {
-        nodes {
-          slug
-        }
-      }
-    }
-  `;
-  const response = await fetchApi<AllThematicsSlug>(query, null);
-  return response.thematics.nodes;
-};
-
-export const getAllThematics = async (): Promise<ThematicPreview[]> => {
-  // 10 000 is an arbitrary number that I use for small websites.
-  const query = gql`
-    query AllThematics {
-      thematics(
-        first: 10000
-        where: { orderby: { field: TITLE, order: ASC } }
-      ) {
-        nodes {
-          databaseId
-          slug
-          title
-        }
-      }
-    }
-  `;
-
-  const response = await fetchApi<AllThematics>(query, null);
-  return response.thematics.nodes;
-};
-
-export const getEndCursor = async ({
-  first = 10,
-}: {
-  first: number;
-}): Promise<string> => {
-  const query = gql`
-    query EndCursorAfter($first: Int) {
-      posts(first: $first) {
-        pageInfo {
-          hasNextPage
-          endCursor
-        }
-      }
-    }
-  `;
-
-  const variables = { first };
-  const response = await fetchApi<LastPostCursor>(query, variables);
-
-  return response.posts.pageInfo.endCursor;
-};
diff --git a/src/ts/types/app.ts b/src/ts/types/app.ts
deleted file mode 100644
index 4243762..0000000
--- a/src/ts/types/app.ts
+++ /dev/null
@@ -1,160 +0,0 @@
-import { NextPage } from 'next';
-import { AppProps } from 'next/app';
-import { ImageProps } from 'next/image';
-import { ReactElement, ReactNode } from 'react';
-import { PostBy, TotalArticles } from './articles';
-import { AllPostsSlug, LastPostCursor, RawPostsList } from './blog';
-import { CommentData, CommentsByPostId, CreateComment } from './comments';
-import { ContactData, SendEmail } from './contact';
-import {
-  AllTopics,
-  AllTopicsSlug,
-  AllThematics,
-  AllThematicsSlug,
-  TopicBy,
-  ThematicBy,
-} from './taxonomies';
-
-//==============================================================================
-// Next
-//==============================================================================
-
-export type NextPageWithLayout<P = {}> = NextPage<P> & {
-  getLayout?: (page: ReactElement) => ReactNode;
-};
-
-export type AppPropsWithLayout = AppProps & {
-  Component: NextPageWithLayout;
-};
-
-//==============================================================================
-// API
-//==============================================================================
-
-export type VariablesType<T> = T extends PostBy | TopicBy | ThematicBy
-  ? Slug
-  : T extends RawPostsList
-  ? CursorPagination
-  : T extends CommentsByPostId
-  ? { id: number }
-  : T extends CreateComment
-  ? CommentData
-  : T extends LastPostCursor
-  ? { first: number }
-  : T extends SendEmail
-  ? ContactData
-  : null;
-
-export type RequestType =
-  | AllPostsSlug
-  | AllTopics
-  | AllTopicsSlug
-  | AllThematics
-  | AllThematicsSlug
-  | CommentsByPostId
-  | CreateComment
-  | LastPostCursor
-  | PostBy
-  | RawPostsList
-  | SendEmail
-  | ThematicBy
-  | TopicBy
-  | TotalArticles;
-
-//==============================================================================
-// Globals
-//==============================================================================
-
-export type ButtonKind = 'primary' | 'secondary' | 'tertiary';
-
-export type ButtonPosition = 'left' | 'right' | 'center';
-
-export type ContentInfo = {
-  readingTime: number;
-  wordsCount: number;
-};
-
-export type ContentParts = {
-  afterMore: string;
-  beforeMore: string;
-};
-
-export type CursorPagination = {
-  first: number;
-  after: string;
-};
-
-export type Dates = {
-  publication: string;
-  update: string;
-};
-
-export type Heading = {
-  depth: number;
-  id: string;
-  children: Heading[];
-  title: string;
-};
-
-export type Meta = {
-  title: string;
-  publishedOn: string;
-  updatedOn: string;
-};
-
-export type MetaKind = 'article' | 'list';
-
-export type NoticeType = 'error' | 'info' | 'success' | 'warning';
-
-export type PageInfo = {
-  endCursor: string;
-  hasNextPage: boolean;
-  total: number;
-};
-
-export type ParamsIds = {
-  params: { id: string };
-};
-
-export type ParamsSlug = {
-  params: { slug: string };
-};
-
-export type Project = {
-  cover?: string;
-  id: string;
-  intro: string;
-  meta: ProjectMeta;
-  slug: string;
-  tagline?: string;
-  title: string;
-  seo: {
-    title: string;
-    description: string;
-  };
-};
-
-export type ProjectMeta = Omit<Meta, 'title'> & {
-  hasCover: boolean;
-  license: string;
-  repos?: {
-    github?: string;
-    gitlab?: string;
-  };
-  technologies?: string[];
-};
-
-export type ProjectProps = {
-  project: Project;
-};
-
-export type ResponsiveImageProps = ImageProps & {
-  caption?: string;
-  linkTarget?: string;
-};
-
-export type Slug = {
-  slug: string;
-};
-
-export type TitleLevel = 2 | 3 | 4 | 5 | 6;
diff --git a/src/ts/types/articles.ts b/src/ts/types/articles.ts
deleted file mode 100644
index 64d2860..0000000
--- a/src/ts/types/articles.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-import { ContentInfo, ContentParts, Dates } from './app';
-import { Comment } from './comments';
-import { Cover, RawCover } from './cover';
-import { SEO } from './seo';
-import { RawTopicPreview, TopicPreview, ThematicPreview } from './taxonomies';
-
-export type ArticleAuthor = {
-  firstName: string;
-  lastName: string;
-  name: string;
-};
-
-export type RawACFPosts = {
-  postsInTopic: RawTopicPreview[] | null;
-  postsInThematic: ThematicPreview[] | null;
-};
-
-export type ACFPosts = {
-  postsInTopic: TopicPreview[] | null;
-  postsInThematic: ThematicPreview[] | null;
-};
-
-export type ArticleMeta = {
-  author?: ArticleAuthor;
-  commentCount?: number;
-  dates?: Dates;
-  readingTime?: number;
-  results?: number;
-  topics?: TopicPreview[];
-  thematics?: ThematicPreview[];
-  website?: string;
-  wordsCount?: number;
-};
-
-export type Article = {
-  author: ArticleAuthor;
-  commentCount: number | null;
-  content: string;
-  databaseId: number;
-  dates: Dates;
-  featuredImage: Cover;
-  id: string;
-  info: ContentInfo;
-  intro: string;
-  seo: SEO;
-  topics: TopicPreview[] | [];
-  thematics: ThematicPreview[] | [];
-  title: string;
-};
-
-export type RawArticle = Pick<
-  Article,
-  'commentCount' | 'databaseId' | 'id' | 'info' | 'seo' | 'title'
-> & {
-  acfPosts: RawACFPosts;
-  author: { node: ArticleAuthor };
-  contentParts: ContentParts;
-  date: string;
-  featuredImage: RawCover;
-  modified: string;
-};
-
-export type ArticlePreview = Pick<
-  Article,
-  | 'commentCount'
-  | 'dates'
-  | 'id'
-  | 'info'
-  | 'intro'
-  | 'topics'
-  | 'thematics'
-  | 'title'
-> & { featuredImage: Cover; slug: string };
-
-export type RawArticlePreview = Pick<
-  Article,
-  'commentCount' | 'id' | 'info' | 'title'
-> & {
-  acfPosts: ACFPosts;
-  contentParts: Pick<ContentParts, 'beforeMore'>;
-  date: string;
-  featuredImage: RawCover;
-  modified: string;
-  slug: string;
-};
-
-export type PostBy = {
-  post: RawArticle;
-};
-
-export type ArticleProps = {
-  comments: Comment[];
-  post: Article;
-};
-
-export type TotalArticles = {
-  posts: {
-    pageInfo: {
-      total: number;
-    };
-  };
-};
diff --git a/src/ts/types/blog.ts b/src/ts/types/blog.ts
deleted file mode 100644
index 05bdd1f..0000000
--- a/src/ts/types/blog.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { PageInfo, Slug } from './app';
-import { ArticlePreview, RawArticlePreview } from './articles';
-import { ThematicPreview, TopicPreview } from './taxonomies';
-
-export type PostsList = {
-  posts: ArticlePreview[];
-  pageInfo: PageInfo;
-};
-
-export type PostsListEdges = {
-  cursor: string;
-  node: RawArticlePreview;
-};
-
-export type RawPostsList = {
-  posts: {
-    edges: PostsListEdges[];
-    pageInfo: PageInfo;
-  };
-};
-
-export type LastPostCursor = {
-  posts: {
-    pageInfo: {
-      endCursor: string;
-    };
-  };
-};
-
-export type AllPostsSlug = {
-  posts: {
-    nodes: Slug[];
-  };
-};
-
-export type BlogPageProps = {
-  allThematics: ThematicPreview[];
-  allTopics: TopicPreview[];
-  posts: PostsList;
-  totalPosts: number;
-};
diff --git a/src/ts/types/comments.ts b/src/ts/types/comments.ts
deleted file mode 100644
index aa3fac3..0000000
--- a/src/ts/types/comments.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-//==============================================================================
-// Comments query
-//==============================================================================
-
-export type CommentAuthor = {
-  name: string;
-  gravatarUrl: string;
-  url: string;
-};
-
-export type RawCommentAuthor = {
-  node: CommentAuthor;
-};
-
-export type Comment = {
-  approved: '';
-  author: CommentAuthor;
-  databaseId: number;
-  content: string;
-  date: string;
-  parentDatabaseId: number;
-  replies: Comment[];
-};
-
-export type RawComment = Omit<Comment, 'author' | 'replies'> & {
-  author: RawCommentAuthor;
-};
-
-export type CommentsNode = {
-  nodes: RawComment[];
-};
-
-export type CommentsByPostId = {
-  comments: CommentsNode;
-};
-
-//==============================================================================
-// Comment mutations
-//==============================================================================
-
-export type CommentData = {
-  author: string;
-  authorEmail: string;
-  authorUrl: string;
-  content: string;
-  parent: number;
-  commentOn: number;
-  mutationId: string;
-};
-
-export type CreatedComment = {
-  clientMutationId: string;
-  success: boolean;
-  comment: null | {
-    approved: boolean;
-  };
-};
-
-export type CreateComment = {
-  createComment: CreatedComment;
-};
diff --git a/src/ts/types/contact.ts b/src/ts/types/contact.ts
deleted file mode 100644
index ef6847a..0000000
--- a/src/ts/types/contact.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-export type ContactData = {
-  body: string;
-  mutationId: string;
-  replyTo: string;
-  subject: string;
-};
-
-export type SentEmail = {
-  clientMutationId: string;
-  message: string;
-  origin: string;
-  replyTo: string;
-  sent: boolean;
-  to: string;
-};
-
-export type SendEmail = {
-  sendEmail: SentEmail;
-};
diff --git a/src/ts/types/cover.ts b/src/ts/types/cover.ts
deleted file mode 100644
index 4df898e..0000000
--- a/src/ts/types/cover.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-export type Cover = {
-  altText: string;
-  sourceUrl: string;
-  title: string;
-} | null;
-
-export type RawCover = {
-  node: Cover;
-} | null;
diff --git a/src/ts/types/nav.ts b/src/ts/types/nav.ts
deleted file mode 100644
index 7cfc46b..0000000
--- a/src/ts/types/nav.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export type NavItem = {
-  id: string;
-  name: string;
-  slug: string;
-};
diff --git a/src/ts/types/prism.ts b/src/ts/types/prism.ts
deleted file mode 100644
index 663bc08..0000000
--- a/src/ts/types/prism.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-export type PrismLanguages =
-  | 'apacheconf'
-  | 'bash'
-  | 'css'
-  | 'diff'
-  | 'docker'
-  | 'editorconfig'
-  | 'ejs'
-  | 'git'
-  | 'graphql'
-  | 'html'
-  | 'ignore'
-  | 'ini'
-  | 'javascript'
-  | 'jsdoc'
-  | 'json'
-  | 'jsx'
-  | 'makefile'
-  | 'markup'
-  | 'php'
-  | 'phpdoc'
-  | 'regex'
-  | 'scss'
-  | 'shell-session'
-  | 'smarty'
-  | 'tcl'
-  | 'toml'
-  | 'tsx'
-  | 'twig'
-  | 'yaml';
-
-export type PrismDefaultPlugins =
-  | 'autoloader'
-  | 'color-scheme'
-  | 'copy-to-clipboard'
-  | 'match-braces'
-  | 'normalize-whitespace'
-  | 'show-language'
-  | 'toolbar';
-
-export type PrismPlugins =
-  | 'command-line'
-  | 'diff-highlight'
-  | 'inline-color'
-  | 'line-highlight'
-  | 'line-numbers';
-
-export type PrismProviderProps = {
-  language: PrismLanguages;
-  plugins: PrismPlugins[];
-};
diff --git a/src/ts/types/repos.ts b/src/ts/types/repos.ts
deleted file mode 100644
index 7dacacc..0000000
--- a/src/ts/types/repos.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-export type RepoData = {
-  created_at: string;
-  updated_at: string;
-  stargazers_count: number;
-};
-
-export type RepoAPI = 'github';
diff --git a/src/ts/types/seo.ts b/src/ts/types/seo.ts
deleted file mode 100644
index 18e3c95..0000000
--- a/src/ts/types/seo.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export type SEO = {
-  title: string;
-  metaDesc: string;
-  metaRobotsNofollow: string;
-  metaRobotsNoindex: string;
-};
diff --git a/src/ts/types/taxonomies.ts b/src/ts/types/taxonomies.ts
deleted file mode 100644
index 17fc022..0000000
--- a/src/ts/types/taxonomies.ts
+++ /dev/null
@@ -1,114 +0,0 @@
-import { ContentInfo, ContentParts, Dates, Slug } from './app';
-import { ArticlePreview, RawArticlePreview } from './articles';
-import { Cover, RawCover } from './cover';
-import { SEO } from './seo';
-
-//==============================================================================
-// Taxonomies base
-//==============================================================================
-
-type Taxonomy = {
-  content: string;
-  databaseId: number;
-  dates: Dates;
-  id: string;
-  info: ContentInfo;
-  intro: string;
-  posts: ArticlePreview[];
-  seo: SEO;
-  title: string;
-};
-
-type TaxonomyPreview = Pick<
-  Taxonomy,
-  'databaseId' | 'id' | 'info' | 'seo' | 'title'
-> & {
-  slug: string;
-};
-
-//==============================================================================
-// Topics
-//==============================================================================
-
-export type Topic = Taxonomy & {
-  featuredImage: Cover;
-  officialWebsite: string;
-};
-
-export type RawTopicPreview = TaxonomyPreview & {
-  featuredImage: RawCover;
-};
-
-export type TopicPreview = TaxonomyPreview & {
-  featuredImage: Cover;
-};
-
-export type AllTopics = {
-  topics: {
-    nodes: TopicPreview[];
-  };
-};
-
-export type RawTopic = TopicPreview & {
-  acfTopics: {
-    officialWebsite: string;
-    postsInTopic: RawArticlePreview[];
-  };
-  contentParts: ContentParts;
-  date: string;
-  featuredImage: RawCover;
-  modified: string;
-};
-
-export type TopicBy = {
-  topic: RawTopic;
-};
-
-export type AllTopicsSlug = {
-  topics: {
-    nodes: Slug[];
-  };
-};
-
-export type TopicProps = {
-  allTopics: TopicPreview[];
-  topic: Topic;
-};
-
-//==============================================================================
-// Thematics
-//==============================================================================
-
-export type Thematic = Taxonomy;
-
-export type ThematicPreview = TaxonomyPreview;
-
-export type AllThematics = {
-  thematics: {
-    nodes: ThematicPreview[];
-  };
-};
-
-export type RawThematic = TaxonomyPreview & {
-  acfThematics: {
-    postsInThematic: RawArticlePreview[];
-  };
-  contentParts: ContentParts;
-  date: string;
-  modified: string;
-};
-
-export type ThematicBy = {
-  thematic: RawThematic;
-};
-
-export type AllThematicsSlug = {
-  thematics: {
-    nodes: Slug[];
-  };
-};
-
-export type ThematicProps = {
-  allThematics: ThematicPreview[];
-  thematic: Thematic;
-};
diff --git a/src/utils/helpers/format.ts b/src/utils/helpers/format.ts
deleted file mode 100644
index 47a7b57..0000000
--- a/src/utils/helpers/format.ts
+++ /dev/null
@@ -1,332 +0,0 @@
-import { ParamsIds, ParamsSlug, Slug } from '@ts/types/app';
-import {
-  Article,
-  ArticlePreview,
-  RawArticle,
-  RawArticlePreview,
-} from '@ts/types/articles';
-import { Comment, RawComment } from '@ts/types/comments';
-import {
-  RawTopic,
-  RawTopicPreview,
-  RawThematic,
-  Topic,
-  TopicPreview,
-  Thematic,
-} from '@ts/types/taxonomies';
-import { settings } from '@utils/config';
-
-/**
- * Format a post preview from RawArticlePreview to ArticlePreview type.
- * @param rawPost - A post preview coming from WP GraphQL.
- * @returns A formatted post preview.
- */
-export const getFormattedPostPreview = (rawPost: RawArticlePreview) => {
-  const {
-    acfPosts,
-    commentCount,
-    contentParts,
-    date,
-    featuredImage,
-    id,
-    info,
-    modified,
-    slug,
-    title,
-  } = rawPost;
-
-  const dates = {
-    publication: date,
-    update: modified,
-  };
-
-  const topics = acfPosts.postsInTopic ? acfPosts.postsInTopic : [];
-  const thematics = acfPosts.postsInThematic ? acfPosts.postsInThematic : [];
-
-  const formattedPost: ArticlePreview = {
-    commentCount,
-    dates,
-    featuredImage: featuredImage ? featuredImage.node : null,
-    id,
-    info,
-    intro: contentParts.beforeMore,
-    slug,
-    topics,
-    thematics,
-    title,
-  };
-
-  return formattedPost;
-};
-
-/**
- * Format an array of posts list from RawArticlePreview to ArticlePreview type.
- * @param rawPosts - A posts list coming from WP GraphQL.
- * @returns A formatted posts list.
- */
-export const getFormattedPostsList = (
-  rawPosts: RawArticlePreview[]
-): ArticlePreview[] => {
-  return rawPosts
-    .filter((post) => Object.getOwnPropertyNames(post).length > 0)
-    .map((post) => {
-      return getFormattedPostPreview(post);
-    });
-};
-
-/**
- * Format a topic from RawTopic to Topic type.
- * @param rawTopic - A topic coming from WP GraphQL.
- * @returns A formatted topic.
- */
-export const getFormattedTopic = (rawTopic: RawTopic): Topic => {
-  const {
-    acfTopics,
-    contentParts,
-    databaseId,
-    date,
-    featuredImage,
-    id,
-    info,
-    modified,
-    seo,
-    title,
-  } = rawTopic;
-
-  const dates = {
-    publication: date,
-    update: modified,
-  };
-
-  const posts = getFormattedPostsList(acfTopics.postsInTopic);
-
-  const formattedTopic: Topic = {
-    content: contentParts.afterMore,
-    databaseId,
-    dates,
-    featuredImage: featuredImage ? featuredImage.node : null,
-    id,
-    info,
-    intro: contentParts.beforeMore,
-    officialWebsite: acfTopics.officialWebsite,
-    posts,
-    seo,
-    title,
-  };
-
-  return formattedTopic;
-};
-
-/**
- * Format a thematic from RawThematic to Thematic type.
- * @param rawThematic - A thematic coming from wP GraphQL.
- * @returns A formatted thematic.
- */
-export const getFormattedThematic = (rawThematic: RawThematic): Thematic => {
-  const {
-    acfThematics,
-    contentParts,
-    databaseId,
-    date,
-    id,
-    info,
-    modified,
-    seo,
-    title,
-  } = rawThematic;
-
-  const dates = {
-    publication: date,
-    update: modified,
-  };
-
-  const posts = getFormattedPostsList(acfThematics.postsInThematic);
-
-  const formattedThematic: Thematic = {
-    content: contentParts.afterMore,
-    databaseId,
-    dates,
-    id,
-    info,
-    intro: contentParts.beforeMore,
-    posts,
-    seo,
-    title,
-  };
-
-  return formattedThematic;
-};
-
-/**
- * Format a comments list from RawComment to Comment type.
- * @param rawComments - A comments list coming from WP GraphQL.
- * @returns A formatted comments list.
- */
-export const getFormattedComments = (rawComments: RawComment[]): Comment[] => {
-  const formattedComments: Comment[] = rawComments.map((comment) => {
-    const formattedComment: Comment = {
-      ...comment,
-      author: comment.author.node,
-      replies: [],
-    };
-
-    return formattedComment;
-  });
-
-  return formattedComments;
-};
-
-/**
- * Create a comments tree with replies.
- * @param comments - A flatten comments list.
- * @returns An array of comments with replies.
- */
-export const buildCommentsTree = (comments: Comment[]) => {
-  type CommentsHashTable = {
-    [key: string]: Comment;
-  };
-
-  const hashTable: CommentsHashTable = Object.create(null);
-  const commentsTree: Comment[] = [];
-
-  comments.forEach(
-    (comment) => (hashTable[comment.databaseId] = { ...comment, replies: [] })
-  );
-
-  comments.forEach((comment) => {
-    if (!comment.parentDatabaseId) {
-      commentsTree.push(hashTable[comment.databaseId]);
-    } else {
-      hashTable[comment.parentDatabaseId].replies.push(
-        hashTable[comment.databaseId]
-      );
-    }
-  });
-
-  return commentsTree;
-};
-
-export const getFormattedTopicsPreview = (
-  topics: RawTopicPreview[]
-): TopicPreview[] => {
-  const formattedTopics: TopicPreview[] = topics.map((topic) => {
-    return {
-      ...topic,
-      featuredImage: topic.featuredImage ? topic.featuredImage.node : null,
-    };
-  });
-
-  return formattedTopics;
-};
-
-/**
- * Format an article from RawArticle to Article type.
- * @param rawPost - An article coming from WP GraphQL.
- * @returns A formatted article.
- */
-export const getFormattedPost = (rawPost: RawArticle): Article => {
-  const {
-    acfPosts,
-    author,
-    commentCount,
-    contentParts,
-    databaseId,
-    date,
-    featuredImage,
-    id,
-    info,
-    modified,
-    seo,
-    title,
-  } = rawPost;
-
-  const dates = {
-    publication: date,
-    update: modified,
-  };
-
-  const topics = acfPosts.postsInTopic
-    ? getFormattedTopicsPreview(acfPosts.postsInTopic)
-    : [];
-
-  const formattedPost: Article = {
-    author: author.node,
-    commentCount,
-    content: contentParts.afterMore,
-    databaseId,
-    dates,
-    featuredImage: featuredImage ? featuredImage.node : null,
-    id,
-    info,
-    intro: contentParts.beforeMore,
-    seo,
-    topics,
-    thematics: acfPosts.postsInThematic ? acfPosts.postsInThematic : [],
-    title,
-  };
-
-  return formattedPost;
-};
-
-/**
- * Converts a date to a string by using the specified locale.
- * @param {string} date - The date.
- * @param {string} [locale] - A locale.
- * @returns {string} The formatted date to locale date string.
- */
-export const getFormattedDate = (
-  date: string,
-  locale: string = settings.locales.defaultLocale
-): string => {
-  const dateOptions: Intl.DateTimeFormatOptions = {
-    day: 'numeric',
-    month: 'long',
-    year: 'numeric',
-  };
-
-  return new Date(date).toLocaleDateString(locale, dateOptions);
-};
-
-/**
- * Converts a date to a time string by using the specified locale.
- * @param {string} date - The date.
- * @param {string} [locale] - A locale.
- * @returns {string} The formatted time to locale date string.
- */
-export const getFormattedTime = (
-  date: string,
-  locale: string = settings.locales.defaultLocale
-): string => {
-  const time = new Date(date).toLocaleTimeString(locale, {
-    hour: 'numeric',
-    minute: 'numeric',
-  });
-
-  return locale === 'fr' ? time.replace(':', 'h') : time;
-};
-
-/**
- * Convert an array of slugs to an array of params with slug.
- * @param {Slug} array - An array of object with slug.
- * @returns {ParamsSlug} An array of params with slug.
- */
-export const getFormattedPaths = (array: Slug[]): ParamsSlug[] => {
-  return array.map((object) => {
-    return { params: { slug: object.slug } };
-  });
-};
-
-/**
- * Convert a number of pages to an array of params with ids.
- * @param {number} totalPages - The total pages.
- * @returns {ParamsIds} An array of params with ids.
- */
-export const getFormattedPageNumbers = (totalPages: number): ParamsIds[] => {
-  const paths = [];
-
-  for (let i = 1; i <= totalPages; i++) {
-    paths.push({ params: { id: `${i}` } });
-  }
-
-  return paths;
-};
diff --git a/src/utils/helpers/i18n.ts b/src/utils/helpers/i18n.ts
index c4734ad..5d19c8c 100644
--- a/src/utils/helpers/i18n.ts
+++ b/src/utils/helpers/i18n.ts
@@ -3,7 +3,7 @@ import { settings } from '@utils/config';
 import { readFile } from 'fs/promises';
 import path from 'path';
 
-type Messages = { [key: string]: string };
+export type Messages = { [key: string]: string };
 
 export const defaultLocale = settings.locales.defaultLocale;
 
diff --git a/src/utils/helpers/prism.ts b/src/utils/helpers/prism.ts
deleted file mode 100644
index a5f5787..0000000
--- a/src/utils/helpers/prism.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Check if the current block has a defined language.
- * @param classList - A list of class.
- * @returns {boolean} - True if a class starts with "language-".
- */
-const isLanguageBlock = (classList: DOMTokenList) => {
-  const classes = Array.from(classList);
-  return classes.some((className) => /language-.*/.test(className));
-};
-
-/**
- * Add automatically some classes and attributes for PrismJs.
- *
- * These classes and attributes are needed by Prism or to customize comments.
- */
-export const addPrismClasses = () => {
-  const preTags = document.getElementsByTagName('pre');
-
-  Array.from(preTags).forEach((preTag) => {
-    if (!isLanguageBlock(preTag.classList)) return;
-
-    preTag.classList.add('match-braces');
-
-    if (preTag.classList.contains('filter-output')) {
-      preTag.setAttribute('data-filter-output', '#output#');
-    }
-
-    if (preTag.classList.contains('language-bash')) {
-      preTag.classList.add('command-line');
-    } else if (!preTag.classList.contains('language-diff')) {
-      preTag.classList.add('line-numbers');
-    }
-  });
-};
diff --git a/src/utils/helpers/projects.ts b/src/utils/helpers/projects.ts
deleted file mode 100644
index 1612dae..0000000
--- a/src/utils/helpers/projects.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import { Project, ProjectMeta } from '@ts/types/app';
-import { readdirSync } from 'fs';
-import path from 'path';
-
-/**
- * Retrieve project's data by id.
- * @param {string} id - The filename without extension.
- * @returns {Promise<Project>} - The project data.
- */
-export const getProjectData = async (id: string): Promise<Project> => {
-  try {
-    const {
-      intro,
-      meta,
-      seo,
-      tagline,
-    }: {
-      intro: string;
-      meta: ProjectMeta & { title: string };
-      seo: { title: string; description: string };
-      tagline?: string;
-    } = await import(`../../content/projects/${id}.mdx`);
-
-    const { title, ...onlyMeta } = meta;
-
-    return {
-      id,
-      intro: intro || '',
-      meta: onlyMeta || {},
-      slug: id,
-      title,
-      seo: seo || {},
-      tagline: tagline || '',
-    };
-  } catch (err) {
-    console.error(err);
-    throw err;
-  }
-};
-
-/**
- * Retrieve the projects data from filenames.
- * @param {string[]} filenames - An array of filenames.
- * @returns {Promise<Project[]>} An array of projects with meta.
- */
-const getProjectsWithMeta = async (filenames: string[]): Promise<Project[]> => {
-  return Promise.all(
-    filenames.map(async (filename) => {
-      return getProjectData(filename);
-    })
-  );
-};
-
-/**
- * Method to sort an array of projects by publication date.
- * @param {Project} a - A single project.
- * @param {Project} b - A single project.
- * @returns The result used by Array.sort() method: 1 || -1 || 0.
- */
-const sortProjectByPublicationDate = (a: Project, b: Project) => {
-  if (a.meta.publishedOn < b.meta.publishedOn) return 1;
-  if (a.meta.publishedOn > b.meta.publishedOn) return -1;
-  return 0;
-};
-
-/**
- * Retrieve all the projects filename.
- * @returns {string[]} An array of filenames.
- */
-export const getAllProjectsFilename = (): string[] => {
-  const projectsDirectory = path.join(process.cwd(), 'src/content/projects');
-  const filenames = readdirSync(projectsDirectory);
-
-  return filenames.map((filename) => filename.replace(/\.mdx$/, ''));
-};
-
-/**
- * Retrieve all projects in content folder sorted by publication date.
- * @returns {Promise<Project[]>} An array of projects.
- */
-export const getSortedProjects = async (): Promise<Project[]> => {
-  const filenames = getAllProjectsFilename();
-  const projects = await getProjectsWithMeta(filenames);
-
-  return [...projects].sort(sortProjectByPublicationDate);
-};
diff --git a/src/utils/helpers/sort.ts b/src/utils/helpers/sort.ts
deleted file mode 100644
index c1ee35d..0000000
--- a/src/utils/helpers/sort.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { ArticlePreview } from '@ts/types/articles';
-import { PostsList } from '@ts/types/blog';
-
-type YearCollection = {
-  [key: string]: ArticlePreview[];
-};
-
-export const sortPostsByYear = (data: PostsList[]) => {
-  const yearCollection: YearCollection = {};
-
-  data.forEach((page) => {
-    page.posts.forEach((post) => {
-      const postYear = new Date(post.dates.publication)
-        .getFullYear()
-        .toString();
-      yearCollection[postYear] = [...(yearCollection[postYear] || []), post];
-    });
-  });
-
-  return yearCollection;
-};
diff --git a/src/utils/hooks/useGithubApi.tsx b/src/utils/hooks/useGithubApi.tsx
deleted file mode 100644
index 4b0b3b2..0000000
--- a/src/utils/hooks/useGithubApi.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import { RepoData } from '@ts/types/repos';
-import useSWR, { Fetcher } from 'swr';
-
-const fetcher: Fetcher<RepoData, string> = (...args) =>
-  fetch(...args).then((res) => res.json());
-
-/**
- * Retrieve data from Github API.
- * @param repo The repo name. Format: "User/project-slug".
- * @returns {object} The data and two booleans to determine if is loading/error.
- */
-const useGithubApi = (repo: string) => {
-  const apiUrl = repo ? `https://api.github.com/repos/${repo}` : null;
-  const { data, error } = useSWR<RepoData>(apiUrl, fetcher);
-
-  return {
-    data,
-    isLoading: !error && !data,
-    isError: error,
-  };
-};
-
-export default useGithubApi;
diff --git a/src/utils/hooks/useHeadingsTree.tsx b/src/utils/hooks/useHeadingsTree.tsx
deleted file mode 100644
index f2be406..0000000
--- a/src/utils/hooks/useHeadingsTree.tsx
+++ /dev/null
@@ -1,104 +0,0 @@
-import { Heading } from '@ts/types/app';
-import { slugify } from '@utils/helpers/slugify';
-import { useRouter } from 'next/router';
-import { useCallback, useEffect, useMemo, useState } from 'react';
-
-const useHeadingsTree = (wrapper: string) => {
-  const router = useRouter();
-  const depths = useMemo(() => ['h2', 'h3', 'h4', 'h5', 'h6'], []);
-  const [allHeadings, setAllHeadings] =
-    useState<NodeListOf<HTMLHeadingElement>>();
-
-  useEffect(() => {
-    const query = depths
-      .map((depth) => `${wrapper} > *:not(aside, #comments) ${depth}`)
-      .join(', ');
-    const result: NodeListOf<HTMLHeadingElement> =
-      document.querySelectorAll(query);
-    setAllHeadings(result);
-  }, [depths, wrapper, router.asPath]);
-
-  const [headingsTree, setHeadingsTree] = useState<Heading[]>([]);
-
-  const getElementDepth = useCallback(
-    (el: HTMLHeadingElement) => {
-      return depths.findIndex((depth) => depth === el.localName);
-    },
-    [depths]
-  );
-
-  const formatHeadings = useCallback(
-    (headings: NodeListOf<HTMLHeadingElement>): Heading[] => {
-      const formattedHeadings: Heading[] = [];
-
-      Array.from(headings).forEach((heading) => {
-        const title: string = heading.textContent!;
-        const id = slugify(title);
-        const depth = getElementDepth(heading);
-        const children: Heading[] = [];
-
-        heading.id = id;
-
-        formattedHeadings.push({
-          depth,
-          id,
-          children,
-          title,
-        });
-      });
-
-      return formattedHeadings;
-    },
-    [getElementDepth]
-  );
-
-  const buildSubTree = useCallback(
-    (parent: Heading, currentHeading: Heading): void => {
-      if (parent.depth === currentHeading.depth - 1) {
-        parent.children.push(currentHeading);
-      } else {
-        const lastItem = parent.children[parent.children.length - 1];
-        buildSubTree(lastItem, currentHeading);
-      }
-    },
-    []
-  );
-
-  const buildTree = useCallback(
-    (headings: Heading[]): Heading[] => {
-      const tree: Heading[] = [];
-
-      headings.forEach((heading) => {
-        if (heading.depth === 0) {
-          tree.push(heading);
-        } else {
-          const lastItem = tree[tree.length - 1];
-          buildSubTree(lastItem, heading);
-        }
-      });
-
-      return tree;
-    },
-    [buildSubTree]
-  );
-
-  const getHeadingsList = useCallback(
-    (headings: NodeListOf<HTMLHeadingElement>): Heading[] => {
-      const formattedHeadings = formatHeadings(headings);
-
-      return buildTree(formattedHeadings);
-    },
-    [formatHeadings, buildTree]
-  );
-
-  useEffect(() => {
-    if (allHeadings) {
-      const headingsList = getHeadingsList(allHeadings);
-      setHeadingsTree(headingsList);
-    }
-  }, [allHeadings, getHeadingsList]);
-
-  return headingsTree;
-};
-
-export default useHeadingsTree;
diff --git a/src/utils/providers/ackee.tsx b/src/utils/providers/ackee.tsx
index c103668..0cb0166 100644
--- a/src/utils/providers/ackee.tsx
+++ b/src/utils/providers/ackee.tsx
@@ -1,5 +1,5 @@
 import { useRouter } from 'next/router';
-import { createContext, FC, useContext, useState } from 'react';
+import { createContext, FC, ReactNode, useContext, useState } from 'react';
 import useAckee from 'use-ackee';
 
 export type AckeeProps = {
@@ -10,6 +10,7 @@ export type AckeeProps = {
 };
 
 export type AckeeProviderProps = {
+  children: ReactNode;
   domain: string;
   siteId: string;
   ignoreLocalhost?: boolean;
diff --git a/src/utils/providers/prism-theme.tsx b/src/utils/providers/prism-theme.tsx
index 2ed8454..62bcf56 100644
--- a/src/utils/providers/prism-theme.tsx
+++ b/src/utils/providers/prism-theme.tsx
@@ -2,6 +2,7 @@ import { LocalStorage } from '@services/local-storage';
 import {
   createContext,
   FC,
+  ReactNode,
   useCallback,
   useContext,
   useEffect,
@@ -22,6 +23,7 @@ export type UsePrismThemeProps = {
 
 export type PrismThemeProviderProps = {
   attribute?: string;
+  children: ReactNode;
   storageKey?: string;
   themes?: PrismTheme[];
 };
-- 
cgit v1.2.3

