Browse Source

finish release/0.4

Olivier Massot 1 year ago
parent
commit
98aa919646
100 changed files with 4780 additions and 3818 deletions
  1. 51 0
      .eslintrc.cjs
  2. 0 24
      .eslintrc.yaml
  3. 9 0
      .gitignore
  4. 9 15
      .gitlab-ci.yml
  5. 1 0
      .nuxtignore
  6. 4 5
      .prettierrc
  7. 1 0
      .yarnrc.yml
  8. 17 17
      README.md
  9. 6 6
      app.vue
  10. 13 2
      assets/style/main.scss
  11. 6 1
      assets/style/theme.scss
  12. 0 0
      components/About/Banner.vue
  13. 153 105
      components/About/Chronologie.vue
  14. 66 52
      components/About/Equipe.vue
  15. 38 27
      components/About/FAQ.vue
  16. 84 60
      components/About/Logiciels.vue
  17. 81 52
      components/About/Presentation.vue
  18. 53 30
      components/About/Valeurs.vue
  19. 55 39
      components/Common/ActionMenu.vue
  20. 61 76
      components/Common/Agenda.vue
  21. 9 7
      components/Common/AgendaLink.vue
  22. 9 16
      components/Common/Avantages.vue
  23. 46 16
      components/Common/Banner.vue
  24. 8 10
      components/Common/Card/Benefit.vue
  25. 14 6
      components/Common/Card/Stat.vue
  26. 46 22
      components/Common/Carousel/Clients.vue
  27. 57 48
      components/Common/Carousel/Fonctionnalite.vue
  28. 170 0
      components/Common/Contact.vue
  29. 26 7
      components/Common/ContainerVideo.vue
  30. 20 22
      components/Common/MenuScroll.vue
  31. 31 29
      components/Common/Meta.vue
  32. 125 99
      components/Common/Presentation.vue
  33. 111 85
      components/Common/ReviewSection.vue
  34. 47 47
      components/Common/Share.vue
  35. 169 12
      components/Common/Table/Comparatif.vue
  36. 36 46
      components/Contact/AddressSection.vue
  37. 0 29
      components/Contact/Banner.vue
  38. 130 91
      components/Contact/Form.vue
  39. 42 43
      components/Contact/Map.vue
  40. 0 0
      components/Formation/Banner.vue
  41. 77 96
      components/Formation/Catalogue.vue
  42. 23 8
      components/Formation/Certification.vue
  43. 15 10
      components/Formation/OPCA.vue
  44. 21 25
      components/Formation/Participation.vue
  45. 26 15
      components/Formation/Presentation.vue
  46. 16 16
      components/Formation/Reviews.vue
  47. 33 17
      components/Home/Besoin.vue
  48. 175 116
      components/Home/Caroussel.vue
  49. 81 42
      components/Home/EventAgenda.vue
  50. 37 29
      components/Home/Help.vue
  51. 129 66
      components/Home/Promotion.vue
  52. 78 74
      components/Home/Reviews.vue
  53. 156 100
      components/Home/Solution.vue
  54. 60 60
      components/JoinUs/Form.vue
  55. 51 45
      components/JoinUs/MissionDetail.vue
  56. 72 56
      components/JoinUs/Missions.vue
  57. 33 37
      components/Layout/AnchoredSection.vue
  58. 39 36
      components/Layout/Captcha.vue
  59. 81 29
      components/Layout/FAQ.vue
  60. 128 134
      components/Layout/Footer/Footer.vue
  61. 55 6
      components/Layout/Footer/Prefooter.vue
  62. 0 183
      components/Layout/Footer/Solutions.vue
  63. 31 250
      components/Layout/Navigation.vue
  64. 96 0
      components/Layout/Navigation/Lg.vue
  65. 179 0
      components/Layout/Navigation/Md.vue
  66. 15 18
      components/Layout/Navigation/Topbar.vue
  67. 11 12
      components/Layout/Pagination.vue
  68. 4 7
      components/Layout/UI/SectionTitle.vue
  69. 7 12
      components/Layout/UI/SubTitle.vue
  70. 12 8
      components/Layout/UI/Title.vue
  71. 29 4
      components/Layout/UI/TitlePage.vue
  72. 96 104
      components/Logiciels/Artist/Abonnement.vue
  73. 117 0
      components/Logiciels/Artist/Abonnement/ToSubscribe.vue
  74. 18 14
      components/Logiciels/Artist/Avantages.vue
  75. 33 37
      components/Logiciels/Artist/Comparatif.vue
  76. 56 57
      components/Logiciels/Artist/Fonctionnalites.vue
  77. 43 14
      components/Logiciels/Artist/Formations.vue
  78. 19 16
      components/Logiciels/Artist/Presentation.vue
  79. 8 8
      components/Logiciels/Artist/Reviews.vue
  80. 43 32
      components/Logiciels/Artist/SomeNumbers.vue
  81. 36 29
      components/Logiciels/Manager/Avantages.vue
  82. 67 51
      components/Logiciels/Manager/Fonctionnalites.vue
  83. 38 32
      components/Logiciels/Manager/Formation.vue
  84. 8 7
      components/Logiciels/Manager/Network.vue
  85. 17 18
      components/Logiciels/Manager/Presentation.vue
  86. 22 31
      components/Logiciels/Manager/Reviews.vue
  87. 9 25
      components/Logiciels/Manager/SomeNumbers.vue
  88. 16 10
      components/Logiciels/School/Avantages.vue
  89. 45 51
      components/Logiciels/School/Comparatif.vue
  90. 0 139
      components/Logiciels/School/Contact.vue
  91. 77 83
      components/Logiciels/School/Fonctionnalites.vue
  92. 64 32
      components/Logiciels/School/Formations.vue
  93. 14 15
      components/Logiciels/School/Presentation.vue
  94. 14 14
      components/Logiciels/School/Reviews.vue
  95. 57 63
      components/Logiciels/School/SomeNumbers.vue
  96. 15 6
      components/Logiciels/Title.vue
  97. 48 42
      components/News/Details.vue
  98. 48 36
      components/News/List.vue
  99. 132 145
      components/Webinaire/Catalogue.vue
  100. 46 50
      components/Webinaire/FAQ.vue

+ 51 - 0
.eslintrc.cjs

@@ -0,0 +1,51 @@
+module.exports = {
+  root: true,
+  env: {
+    browser: true,
+    node: true,
+  },
+  parser: 'vue-eslint-parser',
+  parserOptions: {
+    ecmaVersion: 2020,
+    parser: '@typescript-eslint/parser',
+    sourceType: 'module',
+    tsconfigRootDir: __dirname,
+  },
+  extends: [
+    '@nuxtjs/eslint-config-typescript',
+    'plugin:nuxt/recommended',
+    'eslint:recommended',
+    'plugin:@typescript-eslint/recommended',
+    'plugin:vue/vue3-recommended',
+    'plugin:prettier/recommended',
+  ],
+  ignorePatterns: ['.nuxt', 'coverage/*', 'vendor/*', 'dist/*'],
+  plugins: ['vue', '@typescript-eslint'],
+  // add your custom rules here
+  rules: {
+    'no-console': 0, // on autorise les appels à la console (puisque ceux-ci seront de toute façon nettoyés à la compilation)
+    'vue/valid-v-slot': [
+      'error',
+      {
+        allowModifiers: true,
+      },
+    ],
+    'vue/multi-word-component-names': 0,
+    'vue/no-v-html': 0,
+    '@typescript-eslint/ban-ts-comment': 0,
+  },
+  globals: {
+    useRuntimeConfig: 'readonly',
+    navigateTo: 'readonly',
+    computed: 'readonly',
+    ref: 'readonly',
+    definePageMeta: 'readonly',
+    useRouter: 'readonly',
+    useRoute: 'readonly',
+    useI18n: 'readonly',
+    onMounted: 'readonly',
+    useLayoutStore: 'readonly',
+    useClientDevice: 'readonly',
+    useSeoMeta: 'readonly',
+  },
+}

+ 0 - 24
.eslintrc.yaml

@@ -1,24 +0,0 @@
-env:
-  browser: true
-  node: true
-parser: vue-eslint-parser
-parserOptions:
-  parser: '@typescript-eslint/parser'
-  ecmaVersion: 2020
-  sourceType: 'module'
-plugins:
-  - vue
-  - '@typescript-eslint'
-extends:
-  - '@nuxtjs/eslint-config-typescript',
-  - eslint:recommended
-  - plugin:vue/recommended
-  - plugin:nuxt/recommended
-  - plugin:@typescript-eslint/recommended
-  - plugin:vue/vue3-recommended
-  - plugin:prettier/recommended
-rules:
-  vue/multi-word-component-names: off
-  vue/no-multiple-template-root: off
-  eqeqeq: warn
-  strict: off

+ 9 - 0
.gitignore

@@ -8,3 +8,12 @@
 dist
 .DS_Store
 .idea
+
+# https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored
+.pnp.*
+.yarn/*
+!.yarn/patches
+!.yarn/plugins
+!.yarn/releases
+!.yarn/sdks
+!.yarn/versions

+ 9 - 15
.gitlab-ci.yml

@@ -1,24 +1,18 @@
 stages:
   - qa
-  - deploy_test
+
+cache:
+  paths:
+    - ./node_modules
+    - .yarn
 
 before_script:
-  - apt-get install
-  - curl -fsSL https://deb.nodesource.com/setup_14.x | bash -
-  - apt-get install -y nodejs
-  - npm install yarn --force
-  - yarn generate
+  - corepack enable
+  - yarn set version berry
+  - yarn install --network-timeout 10000
+  - HOST=ci yarn prepare
 
 qa:
   stage: qa
   script:
     - yarn lint
-
-#deploy_test:
-#  stage: deploy_test
-#  script:
-#    # - apt-get update -qq && apt-get install -y -qq sshpass
-#    # - ssh exploitation@test5 "cd /var/opentalent/git/portail_v2 && nvm exec yarn deploy && echo 'Deploy successful' "
-#    - ssh exploitation@test3 'ls /tmp'
-#  only:
-#    - home

+ 1 - 0
.nuxtignore

@@ -1,2 +1,3 @@
 .git/*
 coverage
+.idea

+ 4 - 5
.prettierrc

@@ -1,7 +1,6 @@
 {
-  "prettier": {
-    "tabWidth": 2,
-    "singleQuote": true,
-    "semi": false
-  }
+  "trailingComma": "es5",
+  "tabWidth": 2,
+  "semi": false,
+  "singleQuote": true
 }

+ 1 - 0
.yarnrc.yml

@@ -0,0 +1 @@
+nodeLinker: node-modules

+ 17 - 17
README.md

@@ -1,30 +1,30 @@
-# Nuxt 3 Minimal Starter
 
-Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
+[![pipeline status](http://gitlab.2iopenservice.com/opentalent/portail_v2/badges/master/pipeline.svg)](http://gitlab.2iopenservice.com/opentalent/portail_v2/-/commits/master) 
 
+[![Latest Release](http://gitlab.2iopenservice.com/opentalent/portail_v2/-/badges/release.svg)](http://gitlab.2iopenservice.com/opentalent/portail_v2/-/releases) 
 
-## Setup
+# Site Logiciels
 
-Make sure to install the dependencies:
+Le website "vitrine" qui présente les logiciels, formations et autres services de l'entreprise.
+Développé en nuxt3.
 
-    yarn install
+> @see [vuejs.org](https://vuejs.org/guide/introduction.html) : Vue est le framework de base de l'application  
+> @see [nuxtjs.org](https://nuxt.com/docs/getting-started/introduction) : Nuxt est une surcouche à Vue qui automatise et simplifie beaucoup de choses  
+> @see [pinia.vuejs.org](https://pinia.vuejs.org/introduction.html) : Store library that allow you to share a state accross your components / pages  
+> @see [pinia-orm.codedredd.de](https://pinia-orm.codedredd.de/guide/getting-started/quick-start) : Ajoute une gestion par modèles / repos au store Pinia  
+> @see [vuetifyjs.com](https://cdn.vuetifyjs.com/docs/images/logos/vuetify-logo-v3-slim-text-light.svg) : Composants graphiques préconstruits  
+> @see [typescriptlang.org](https://www.typescriptlang.org/) : Typescript
 
-Créer le symlink vers le bon fichier env (remplacer <environnement> par l'env courant):
 
-    ln -s .env.<environnement> .env
+### Installer
 
-## Development Server
+    yarn install
 
-Start the development server on http://localhost:3000
+### Exécuter sur un environnement local
 
-```bash
-yarn dev
-````
+    yarn dev
 
-## SSG
+### Déployer
 
-```bash
-yarn generate
-```
+    yarn generate
 
-Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.

+ 6 - 6
app.vue

@@ -1,17 +1,17 @@
 <template>
-  <div id="top" />
+  <div>
+    <div id="top" />
 
-  <LayoutNavigation />
+    <LayoutNavigation />
 
-  <nuxt-page />
+    <nuxt-page />
 
-  <LayoutFooter />
+    <LayoutFooter />
+  </div>
 </template>
 
 <script setup lang="ts">
-
 const layoutStore = useLayoutStore()
 
 layoutStore.resetAnchoredSections()
-
 </script>

+ 13 - 2
assets/style/main.scss

@@ -3,10 +3,14 @@
 body {
   font-family: "Barlow", serif;
   font-style: normal;
-
+  text-align: justify;
   --banner-center-image: 20%;
 }
 
+.v-container {
+  overflow: hidden;
+}
+
 .table-row {
   background-color: white;
   text-align: center;
@@ -19,11 +23,18 @@ body {
 
 .center-90 {
   width: 90%;
+  max-width: 1600px;
   margin-right: auto;
   margin-left: auto;
+
+  @media (max-width: 600px) {
+    width: 96%;
+  }
 }
 .v-row.center-90 {
   margin: -12px auto;
 }
 
-
+h1, h2, h3, h4, h5, li, .v-btn {
+  text-align: start;
+}

+ 6 - 1
assets/style/theme.scss

@@ -9,8 +9,10 @@ body {
   --on-primary-color: #ffffff;
   --on-primary-color-alt: #caf5f4;
   --secondary-color: #9edbdd;
+  --secondary-color-light: #c6eaeb;
   --on-secondary-color: #262626;
   --neutral-color-alt: #dbdbdb;
+  --neutral-color-alt-light: #f2f2f2;
   --neutral-color-alt-strong: #999999;
   --on-neutral-color-alt: #000000;
 
@@ -29,8 +31,11 @@ body {
   --action-menu-secondary-color: #9edbdd;
   --action-menu-on-secondary-color: #262626;
 
+  --scroll-menu-primary-color: #0e2d32;
+  --scroll-menu-on-primary-color: #ffffff;
+
   --artist-color-light: #fef3ce;
-  --school-color-light: #9edbdd;
+  --school-color-light: #a5d4e5;
   --manager-color-light: #f7cdce;
 }
 

+ 0 - 0
components/About/Banner.vue


+ 153 - 105
components/About/Chronologie.vue

@@ -1,84 +1,66 @@
 <template>
   <AnchoredSection id="history">
     <LayoutContainer class="alt-theme">
-      <v-container >
-        <v-row class="mb-6 mt-6">
-          <v-col cols="6">
+      <v-container>
+        <v-row class="mb-6 mt-6 center-90">
+          <v-col cols="12" md="6">
             <LayoutUISubTitle>
               Découvrez toute notre histoire
             </LayoutUISubTitle>
           </v-col>
 
-          <v-col cols="6">
+          <v-col cols="12" md="6">
             <div class="carousel-controls">
-              <v-btn
-                icon="fas fa-chevron-left"
-                @click="goPrevious"
-              />
-              <v-btn
-                icon="fas fa-chevron-right"
-                @click="goNext"
-              />
+              <v-btn icon="fas fa-chevron-left" @click="goPrevious" />
+              <v-btn icon="fas fa-chevron-right" @click="goNext" />
             </div>
           </v-col>
         </v-row>
       </v-container>
 
-      <v-row class="mb-12">
+      <v-row class="mb-12 center-90">
         <v-col cols="12">
           <Carousel
-            v-model="activeSlide"
             ref="carousel"
-            :items-to-show="2"
+            v-model="activeSlide"
+            :items-to-show="lgAndUp ? 2 : 1"
             :items-to-scroll="1"
-            :wrap-around="true"
           >
             <Slide
               v-for="(slide, index) in slides"
               :key="slide.title"
-              :class="{'active': index === activeSlide}"
+              :class="{ active: index === activeSlide }"
             >
-              <v-row justify="center">
-                <v-col cols="4">
-                  <div class="image-container">
-                    <v-img :src="slide.imageUrl" cover />
-                  </div>
-                </v-col>
+              <div class="card">
+                <div class="image-container">
+                  <v-img :src="slide.imageUrl" cover />
+                </div>
 
-                <v-col cols="4">
-                  <div class="description-container">
-                    <span class="year">
-                      {{ slide.year }}
-                    </span>
+                <div class="description-container">
+                  <span class="year">
+                    {{ slide.year }}
+                  </span>
 
-                    <h4>
-                      {{ slide.title }}
-                    </h4>
+                  <h4 v-html="slide.title" />
 
-                    <p class="mb-6">
-                      {{ slide.description }}
-                    </p>
-                  </div>
-                </v-col>
+                  <p class="mb-6" v-html="slide.description" />
+                </div>
+              </div>
 
-                <div class="timeline-container">
+              <div class="timeline-container">
+                <div v-if="slide.year" class="timeline">
                   <div
-                    v-if="slide.year"
-                    class="timeline"
+                    class="timeline-point"
+                    :style="{
+                      left: computePositionOnTimeline(slide.year) + '%',
+                    }"
                   >
-                    <div
-                      class="timeline-point"
-                      :style="{
-                        left: computePositionOnTimeline(slide.year) + '%',
-                      }"
-                    >
-                      <p class="timeline-year">
-                        {{ slide.year }}
-                      </p>
-                    </div>
+                    <p class="timeline-year">
+                      {{ slide.year }}
+                    </p>
                   </div>
                 </div>
-              </v-row>
+              </div>
             </Slide>
           </Carousel>
         </v-col>
@@ -88,104 +70,115 @@
 </template>
 
 <script setup lang="ts">
-import { useDisplay } from "vuetify";
-import { Carousel, Slide } from "vue3-carousel";
-import "vue3-carousel/dist/carousel.css";
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { ChronologyItem } from "~/types/interface";
+import { useDisplay } from 'vuetify'
+import { Carousel, Slide } from 'vue3-carousel'
+import 'vue3-carousel/dist/carousel.css'
+import type { Ref } from 'vue'
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { ChronologyItem } from '~/types/interface'
 
-const activeSlide: Ref<number> = ref(0);
+const activeSlide: Ref<number> = ref(0)
 
-const { mdAndDown } = useDisplay();
+const { lgAndUp } = useDisplay()
 
-const carousel: Ref<typeof Carousel | null> = ref(null);
+const carousel: Ref<typeof Carousel | null> = ref(null)
 
-const goPrevious = () => carousel.value!.prev();
-const goNext = () => carousel.value!.next();
+const goPrevious = () => carousel.value!.prev()
+const goNext = () => carousel.value!.next()
 
 const computePositionOnTimeline = (year: string) => {
   const intYear = parseInt(year)
 
   if (!intYear || isNaN(intYear)) {
-    return 0;
+    return 0
   }
-  const startYear = 2005;
-  const endYear = 2024;
-  return ((intYear - startYear) / (endYear - startYear)) * 100;
-};
+  const startYear = 2005
+  const endYear = 2024
+  return ((intYear - startYear) / (endYear - startYear)) * 100
+}
 
 const slides: Array<ChronologyItem> = [
   {
-    year: "2005",
+    year: '2005',
     title: "L'origine d'Opentalent",
     description:
       "Sous une pleine lune inspirante, Guillaume alors imagine un outil collaboratif en ligne révolutionnaire pour le secteur culturel. Cette idée germe alors qu'il est président d'orchestre et membre du CA d'une école de musique, marquant le début du concept Opentalent.",
-    imageUrl: "/images/about/Origine-Opentalent-outil-collaboratif-pour-la-culture.jpg",
+    imageUrl:
+      '/images/pages/qui-sommes-nous/chronologie/1-Origine_Opentalent-outil_collaboratif_pour_la_culture.jpg',
   },
   {
-    year: "2006",
-    title: "Développement et partenariat stratégique",
+    year: '2006',
+    title: 'Développement et partenariat stratégique',
     description:
       "Michel, passionné par l'innovation technologique, rejoint Guillaume. Ensemble, ils développent Opentalent avec le soutien de la Fédération de Haute-Savoie. Leur travail acharné bénévole durant 2 ans donne naissance à un logiciel SAS avant-gardiste, une première dans l'univers des structures culturelles.",
-    imageUrl: "/images/about/Developpement-et-partenariat-stratégique-Opentalent.jpg",
+    imageUrl:
+      '/images/pages/qui-sommes-nous/chronologie/2-Developpement_et_partenariat_strategique_Opentalent.jpg',
   },
   {
-    year: "2008",
+    year: '2008',
     title: "Naissance de l'entreprise 2iOpenservice",
     description:
       "La Fédération de Haute-Savoie, séduite par le projet, invite à collaborer avec la CMF, élargissant l'impact d'Opentalent. 2IOpenservice est alors officiellement créée, marquant une nouvelle ère dans la gestion culturelle digitale.  ",
-    imageUrl: "/images/about/idee.png",
+    imageUrl:
+      '/images/pages/qui-sommes-nous/chronologie/3-Naissance_de_l_entreprise_2IOpenservice-Opentalent.jpg',
   },
   {
-    year: "2009",
-    title: "MusAssos - la réponse aux besoins pour les petites structures",
+    year: '2009',
+    title: 'MusAssos - la réponse aux besoins pour les petites structures',
     description:
-      "Pour répondre aux besoins spécifiques des écoles affiliées à la CMF, 2iopenservice lance MusAssos, une solution adapté aux petites et moyennes structures, facilitant la gestion et la promotion culturelle.",
-    imageUrl: "/images/about/idee.png",
+      'Pour répondre aux besoins spécifiques des écoles affiliées à la CMF, 2iopenservice lance MusAssos, une solution adapté aux petites et moyennes structures, facilitant la gestion et la promotion culturelle.',
+    imageUrl:
+      '/images/pages/qui-sommes-nous/chronologie/4-Logiciel_MusAssos-pour_les_petites_et_moyennes_structures.png',
   },
   {
-    year: "2010",
+    year: '2010',
     title: "CMF Réseau <br> l'innovation communautaire",
     description:
       "La CMF adopte AdminFédé pour connecter ses adhérents, et AdminAsso devient accessible à tous, démocratisant l'accès aux outils de gestion artistique.",
-    imageUrl: "/images/about/idee.png",
+    imageUrl:
+      '/images/pages/qui-sommes-nous/chronologie/5-Confédération_Musicale_de_France-CMF_Réseau-AdminFédé_AdminAsso.png',
   },
   {
-    year: "2014",
-    title: "Vers une Culture Multidisciplinaire avec FFEC",
+    year: '2014',
+    title: 'Vers une Culture Multidisciplinaire avec FFEC',
     description:
       "Le logiciel d'Opentalent s'étend au-delà de l'enseignement artistique, embrassant l'art, la musique, le théâtre, la danse et le cirque. En partenariat avec la FFEC, Reso Cirque voit le jour, intégrant notre solution au cœur de la pratique circassienne.",
-    imageUrl: "/images/about/idee.png",
+    imageUrl:
+      '/images/pages/qui-sommes-nous/chronologie/6-FFEC_Reso_Cirque-Ouverture_vers_une_culture_multidisciplinaire.png',
   },
   {
-    year: "2015",
-    title: "Refonte Technologique",
+    year: '2015',
+    title: 'Refonte Technologique',
     description:
-      "Nous modernisons notre gamme de logiciels pour la rendre plus sécurisée et compatible avec divers supports, marquant une étape clé dans notre évolution technologique.",
-    imageUrl: "/images/about/Refonte-du-site-internet-Opentalent-agenda-et-logiciels-culturels.jpg",
+      'Nous modernisons notre gamme de logiciels pour la rendre plus sécurisée et compatible avec divers supports, marquant une étape clé dans notre évolution technologique.',
+    imageUrl:
+      '/images/pages/qui-sommes-nous/chronologie/7-Refonte_technologique_des_logiciels_Opentalent_securitee_modernitee_intuitivitee.jpg',
   },
   {
-    year: "2019",
-    title: "Nouvelle Génération Opentalent",
+    year: '2019',
+    title: 'Nouvelle Génération Opentalent',
     description:
       "Avec des fonctionnalités améliorées et une interface utilisateur intuitive, la nouvelle génération d'Opentalent se démarque, prouvant notre engagement envers l'excellence et l'accessibilité.",
-    imageUrl: "/images/about/Nouvelle-génération-Opentalent-moderne-securisee-experience-optimisee.jpg",
+    imageUrl:
+      '/images/pages/qui-sommes-nous/chronologie/8-Nouvelle_generation_Opentalent_moderne_securisee_experience_optimisee.jpg',
   },
   {
-    year: "2024",
-    title: "Relooking du site Opentalent",
+    year: '2024',
+    title: 'Relooking du site Opentalent',
     description:
-      "Le site Opentalent se réinvente, reflétant notre évolution et notre capacité à nous adapter aux tendances actuelles, tout en conservant notre essence originelle.",
-    imageUrl: "/images/about/idee.png",
+      'Le site Opentalent se réinvente, reflétant notre évolution et notre capacité à nous adapter aux tendances actuelles, tout en conservant notre essence originelle.',
+    imageUrl:
+      '/images/pages/qui-sommes-nous/chronologie/9-Relooking_du_site_internet_Opentalent_agenda_et_logiciels_culturels.jpg',
   },
   {
-    year: "",
-    title: "LE FUTUR AVEC VOUS... ",
+    year: '',
+    title: 'LE FUTUR AVEC VOUS... ',
     description:
-      "Opentalent, plus qu'une gamme de logiciels ou un agenda culturel, c'est une aventure collective. Ensemble, poursuivons cette quête d'innovation et de partage culturel. <br> Rejoignez-nous dans cette aventure passionnante et façonnons l'avenir de la culture. <br> <strong> Opentalent, c'est vous ! </strong>",
-    imageUrl: "/images/about/idee.png",
+      "Opentalent, plus qu'une gamme de logiciels ou un agenda culturel, c'est une aventure collective. Ensemble, poursuivons cette quête d'innovation et de partage culturel. <br> Rejoignez-nous dans cette aventure passionnante et façonnons l'avenir de la culture. <br><br> <strong> OPENTALENT, C'EST VOUS ! </strong>",
+    imageUrl:
+      '/images/pages/qui-sommes-nous/chronologie/10-Opentalent_ensemble_construisons_notre_futur.jpg',
   },
-];
+]
 </script>
 
 <style scoped lang="scss">
@@ -215,18 +208,34 @@ const slides: Array<ChronologyItem> = [
 }
 
 .carousel {
+  padding-bottom: 72px;
+
+  :deep(.carousel__viewport) {
+    overflow: visible;
+  }
+
   .carousel__slide {
     opacity: 0.5;
     transition: opacity 0.3s ease-in-out;
+    display: flex;
+    flex-direction: column;
   }
   .carousel__slide.active {
     opacity: 1;
     transform: scale(1.1);
-    transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out;
+    transition:
+      transform 0.3s ease-in-out,
+      opacity 0.3s ease-in-out;
   }
 
-  .v-row {
-    height: 32rem;
+  .card {
+    display: flex;
+    flex-direction: row;
+    margin-bottom: 18px;
+
+    @media (max-width: 600px) {
+      flex-direction: column;
+    }
   }
 
   .v-col {
@@ -240,6 +249,16 @@ const slides: Array<ChronologyItem> = [
   .description-container {
     height: 300px;
     width: 300px;
+
+    @media (max-width: 1480px) {
+      height: 320px;
+      width: 260px;
+    }
+
+    @media (max-width: 600px) {
+      width: 80%;
+      height: auto;
+    }
   }
 
   .image-container {
@@ -249,13 +268,22 @@ const slides: Array<ChronologyItem> = [
       border-top-left-radius: 20%;
       border-bottom-left-radius: 20%;
     }
+
+    @media (max-width: 600px) {
+      margin: auto;
+
+      .v-img {
+        border-top-left-radius: 20%;
+        border-top-right-radius: 20%;
+        border-bottom-left-radius: 0;
+      }
+    }
   }
 
   .description-container {
     padding: 1rem;
     text-align: center;
-    margin-left: 1rem;
-    background-color: var(--primary-color);
+    background-color: rgba(0, 0, 0, 0.3);
     color: var(--on-primary-color);
     border-top-right-radius: 20%;
     border-bottom-right-radius: 20%;
@@ -266,9 +294,8 @@ const slides: Array<ChronologyItem> = [
     }
 
     h4 {
-      justify-content: flex-end;
-      align-items: center;
       font-size: 1rem;
+      text-align: center;
     }
 
     p {
@@ -277,11 +304,32 @@ const slides: Array<ChronologyItem> = [
       font-size: 0.8rem;
       color: var(--secondary-color);
     }
+
+    @media (max-width: 700px) {
+      padding: 1rem 0;
+
+      h4 {
+        font-size: 1.6rem;
+        text-align: left;
+        padding: 1rem;
+      }
+
+      p {
+        text-align: justify;
+      }
+    }
+
+    @media (max-width: 600px) {
+      margin: auto;
+      border-top-right-radius: 0;
+      border-bottom-left-radius: 20%;
+      border-bottom-right-radius: 20%;
+    }
   }
 }
 
 .timeline-container {
-  width: 90%;
+  width: 70%;
   padding: 10px 0;
 
   .timeline {

+ 66 - 52
components/About/Equipe.vue

@@ -2,33 +2,29 @@
   <AnchoredSection id="team">
     <LayoutContainer class="mb-12">
       <v-row class="mt-12 center-90">
-        <LayoutUISubTitle>
-          Notre équipe
-        </LayoutUISubTitle>
+        <LayoutUISubTitle> Notre équipe </LayoutUISubTitle>
       </v-row>
 
       <v-row class="center-90">
-        <LayoutUITitle>
-          Une équipe spécialisée et passionnée
-        </LayoutUITitle>
+        <LayoutUITitle> Une équipe spécialisée et passionnée </LayoutUITitle>
 
         <span class="details ml-4 mt-6 mb-12">
-          Chez Opentalent, on recherche des compétences mais surtout des hommes et
-          des femmes qui souhaitent s'engager dans un projet porteur de sens.
+          Chez Opentalent, on recherche des compétences mais surtout des hommes
+          et des femmes qui souhaitent s'engager dans un projet porteur de sens.
         </span>
       </v-row>
 
       <v-row class="center-90">
         <v-col
-          cols="12" sm="6" md="4" lg="3"
           v-for="associate in associates"
           :key="associate.name"
+          cols="12"
+          sm="6"
+          md="4"
+          lg="3"
         >
           <v-card>
-            <v-img
-              :src="associate.photo"
-              :height="370"
-            />
+            <v-img :src="associate.photo" :height="370" />
 
             <v-card-title class="name">
               {{ associate.name }}
@@ -43,15 +39,15 @@
 
       <v-row class="center-90">
         <v-col
-          cols="12" sm="6" md="4" lg="3"
           v-for="employee in employees"
           :key="employee.name"
+          cols="12"
+          sm="6"
+          md="4"
+          lg="3"
         >
           <v-card>
-            <v-img
-              :src="employee.photo"
-              :height="370"
-            />
+            <v-img :src="employee.photo" :height="370" />
 
             <v-card-title class="name">
               {{ employee.name }}
@@ -68,64 +64,82 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { SocietyMember } from "~/types/interface";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { SocietyMember } from '~/types/interface'
 
 const associates: Array<SocietyMember> = [
   {
-    name: "Guillaume",
-    position: "Fondateur / DIRECTEUR COMMERCIAL",
-    photo: "/images/about/equipe/Guillaume_CORCOBA-co-fondateur_et_Gerant.png",
+    name: 'Guillaume',
+    position: 'Co-fondateur / Gérant',
+    photo:
+      '/images/pages/qui-sommes-nous/equipe/Guillaume_CORCOBA-co-fondateur_et_Gerant.png',
+    alt: 'Avatar d’un homme avec les cheveux poivre et sel court portant un polo bordeaux et un jean',
   },
   {
-    name: "Michel",
-    position: "FONDATEUR / Directeur développement",
-    photo: "/images/about/equipe/Michel_PERNET-SOLLIET-Co-fondateur_et_Product_Owner.png",
+    name: 'Michel',
+    position: 'Co-fondateur / Product Owner',
+    photo:
+      '/images/pages/qui-sommes-nous/equipe/Michel_PERNET-SOLLIET-Co-fondateur_et_Product_Owner.png',
+    alt: 'Avatar d’un homme avec les cheveux bruns mi-long portant un pull jaune et un pantalon noir',
   },
-];
+]
 
 const employees: Array<SocietyMember> = [
   {
-    name: "Johan",
-    position: " FORMATEUR",
-    photo: "/images/about/equipe/Johan_HAUDIQUET-Formateur_et_Assistance.png",
+    name: 'Johan',
+    position: 'Formation et Assistance',
+    photo:
+      '/images/pages/qui-sommes-nous/equipe/Johan_HAUDIQUET-Formateur_et_Assistance.png',
+    alt: 'Avatar d’un homme avec les cheveux bruns court portant un sweat noir et un pantalon beige',
   },
   {
-    name: "Nathalie",
-    position: "Ch. DEVELOPPEMENT COMMERCIAL",
-    photo: "/images/about/equipe/Nathalie_CHEVALON-Chargee_de_developpement_commercial.png",
+    name: 'Nathalie',
+    position: 'Développement Commercial',
+    photo:
+      '/images/pages/qui-sommes-nous/equipe/Nathalie_CHEVALON-Chargee_de_developpement_commercial.png',
+    alt: 'Avatar d’une femme avec les cheveux bruns mi-long et ondulée portant une chemise noire/blanche et un jean bleu foncé',
   },
   {
-    name: "Laetitia",
-    position: "CH. COMMUNICATION & MARKETING",
-    photo: "/images/about/equipe/Laetitia_SIFFOINTE-Chargee_de_Marketing_et_Communication.png",
+    name: 'Laetitia',
+    position: 'Marketing & Communication',
+    photo:
+      '/images/pages/qui-sommes-nous/equipe/Laetitia_SIFFOINTE-Chargee_de_Marketing_et_Communication.png',
+    alt: 'Avatar d’une femme avec les cheveux blonds long et ondulée portant un pull gris et un jean noir',
   },
   {
-    name: "Florence",
-    position: "ASSISTANTE ADMINISTRATIVE",
-    photo: "/images/about/equipe/Florence_JOANNIDIS-ADV.png",
+    name: 'Florence',
+    position: 'Assistante administrative et commerciale',
+    photo: '/images/pages/qui-sommes-nous/equipe/Florence_JOANNIDIS-ADV.png',
+    alt: 'Avatar d’une femme avec des lunettes, les cheveux bruns long et attaché portant un pull bleu et un jean bleu foncé',
   },
   {
-    name: "Vincent",
-    position: "LEAD DEVELOPPEUR",
-    photo: "/images/about/equipe/Vincent_GUFFON-Lead_dev.png",
+    name: 'Vincent',
+    position: 'Lead developer',
+    photo: '/images/pages/qui-sommes-nous/equipe/Vincent_GUFFON-Lead_dev.png',
+    alt: 'Avatar d’un homme avec les cheveux bruns court avec une barbe rousse portant un tee-shirt noir et un jean bleu',
   },
   {
-    name: "Olivier",
-    position: "DEVELOPPEUR",
-    photo: "/images/about/equipe/Olivier_MASSOT-Developpeur.png",
+    name: 'Olivier',
+    position: 'Développeur',
+    photo:
+      '/images/pages/qui-sommes-nous/equipe/Olivier_MASSOT-Developpeur.png',
+    alt: 'Avatar d’un homme avec les cheveux blonds mi-long et un bouc blond portant un gilet gris et un jean noir',
   },
   {
-    name: "Sébastien",
-    position: "DEVELOPPEUR",
-    photo: "/images/about/equipe/Sebastien_FAVRE-BONTE_Developpeur.png",
+    name: 'Sébastien',
+    position: 'Développeur',
+    photo:
+      '/images/pages/qui-sommes-nous/equipe/Sebastien_FAVRE-BONTE_Developpeur.png',
+    alt: 'Avatar d’un homme avec des lunettes, les cheveux bruns court portant un pull bleu et un jean bleu foncé',
   },
   {
-    name: "Maha",
-    position: "DEVELOPPEUSE",
-    photo: "/images/about/equipe/Maha_BOUCHIBA-Developpeuse.png",
+    name: 'Maha',
+    position: 'Développeuse',
+    photo:
+      '/images/pages/qui-sommes-nous/equipe/Maha_BOUCHIBA-Developpeuse.png',
+    alt: 'Avatar d’une femme portant un turban sur les cheveux, haut beige et blanc et un jean bleu foncé',
   },
-];
+]
 </script>
 
 <style scoped lang="scss">

+ 38 - 27
components/About/FAQ.vue

@@ -2,24 +2,22 @@
   <AnchoredSection id="help">
     <LayoutContainer>
       <v-row no-gutters class="alt-theme">
-        <v-col cols="6">
-           <v-img
-             src="/images/help/Help.png"
-             cover
-           />
+        <v-col cols="12" md="6">
+          <v-img
+            src="/images/pages/qui-sommes-nous/contact/Opentalent_a_votre_service.png"
+            alt="Un homme et une femme tous les deux le sourire aux lèvres se serre la main"
+            cover
+          />
         </v-col>
 
-        <v-col cols="6">
-          <div class="ml-6">
-            <h4 class="ml-12">
-              Chez Opentalent, nous avons à coeur de répondre à vos interrogations
-              et de vous apporter la solution faite pour vous.
+        <v-col cols="12" md="6">
+          <div class="d-flex flex-column">
+            <h4>
+              Chez Opentalent, nous avons à coeur de répondre à vos
+              interrogations et de vous apporter la solution faite pour vous.
             </h4>
 
-            <v-btn
-              to="/nous-contacter"
-              class="ml-12 mt-12"
-            >
+            <v-btn to="/nous-contacter" class="inv-theme mt-12">
               Nous contacter
             </v-btn>
           </div>
@@ -30,40 +28,53 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
 </script>
 
 <style scoped lang="scss">
 .v-col {
-  height: 20rem;
+  height: 25rem;
 }
 
-.help-img {
-  background-repeat: no-repeat;
-  background-position: center;
-  width: 100%;
-  height: 20rem;
+.v-img {
+  height: 25rem;
 }
 
 h4 {
-  margin-bottom: 2rem;
-  margin-top: 3rem;
   font-weight: 400;
   font-size: 2rem;
   line-height: 34px;
-  width: 40rem;
-  margin-right: auto;
+  width: 60%;
+  margin: 3rem auto 2rem auto;
   color: var(--on-primary-color);
+  text-align: justify;
+
+  @media (max-width: 600px) {
+    width: 80%;
+    margin-left: 10%;
+  }
 }
 
 .v-btn {
   width: 195px;
   height: 53px;
-  background: var(--secondary-color);
+  background: var(--secondary-color) !important;
   border-radius: 6px;
   color: var(--on-secondary-color);
   padding: 19px 28px;
   gap: 9px;
-  margin-left: 2rem;
+  margin-right: auto;
+  margin-left: auto;
+
+  @media (max-width: 1240px) {
+    width: 40%;
+    margin-left: 30%;
+    margin-bottom: 48px;
+  }
+
+  @media (max-width: 600px) {
+    width: 80%;
+    margin-left: 10%;
+  }
 }
 </style>

+ 84 - 60
components/About/Logiciels.vue

@@ -2,9 +2,7 @@
   <AnchoredSection id="softwares">
     <LayoutContainer>
       <v-row class="mb-6 center-90">
-        <LayoutUISubTitle>
-          Nos logiciels
-        </LayoutUISubTitle>
+        <LayoutUISubTitle> Nos logiciels </LayoutUISubTitle>
 
         <LayoutUITitle>
           Nos logiciels dédiés à chaque acteur culturel
@@ -12,49 +10,42 @@
       </v-row>
 
       <v-row class="mb-12 center-90">
-        <v-col cols="3">
-          <p class="text-justify mr-4 ml-6 mb-6">
+        <v-col md="3">
+          <p class="text-justify mr-4 ml-2 mb-6">
             Découvrez notre gamme de logiciels de gestion & de communication
             adapté au secteur culturel. <br />
             Des fonctionnalités complètes:
           </p>
 
-          <ul class="ml-6">
-            <li
-              v-for="(feature, index) in features"
-              :key="index"
-            >
+          <ul class="ml-4">
+            <li v-for="(feature, index) in features" :key="index">
               {{ feature }}
             </li>
           </ul>
 
-          <p class="text-justify mr-4 ml-6 mt-6">
-            À chaque logiciel sa spécificité !
+          <p class="text-justify mr-4 mt-6">
+            <b>À chaque logiciel sa spécificité !</b>
           </p>
         </v-col>
 
         <v-col
-          cols="3"
           v-for="(item, index) in items"
           :key="index"
+          cols="12"
+          md="3"
           :class="item.class"
         >
-          <v-img
-            :src="item.imageUrl"
-            cover
-            class="container-image"
-          >
-            <footer>
-              <v-img :src="item.logoUrl" class="logo" />
-
-              <v-btn
-                :to="item.link"
-                class="plus-button"
-              >
-                <v-icon>fas fa-plus</v-icon>
-              </v-btn>
-            </footer>
-          </v-img>
+          <nuxt-link :to="item.link" class="software-link">
+            <v-img :src="item.imageUrl" cover class="container-image">
+              <footer>
+                <v-img :src="item.logoUrl" :alt="item.logoAlt" class="logo" />
+
+                <v-btn class="plus-button">
+                  <v-icon>fas fa-plus</v-icon>
+                </v-btn>
+              </footer>
+            </v-img>
+          </nuxt-link>
         </v-col>
       </v-row>
     </LayoutContainer>
@@ -62,38 +53,57 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
 
 const features: Array<string> = [
-  "Une gestion de vos contacts",
-  "un agenda collaboratif et interactif",
-  "Une gestion du matériel et du stock",
-  "Une communication simplifiée",
+  'Une gestion de vos contacts',
+  'Un agenda collaboratif et interactif',
+  'Une gestion du matériel et du stock',
+  'Une communication simplifiée',
   "Un rapport d'activité complet",
-  "Un site internet intégré",
-  "Et bien plus encore...",
-];
-
-const items: Array<{imageUrl: string, logoUrl: string, class: string, link: string}> = [
+  'Un site internet intégré',
+  'Et bien plus encore...',
+]
+
+const items: Array<{
+  imageUrl: string
+  alt: string
+  logoUrl: string
+  logoAlt: string
+  class: string
+  link: string
+}> = [
   {
-    imageUrl: "/images/solutions/artist.jpg",
-    logoUrl: "/images/logo/logiciels/Artist-Blanc.png",
-    class: "artist",
-    link: "/opentalent_artist",
+    imageUrl:
+      '/images/pages/qui-sommes-nous/logiciels/Opentalent_Artist_pour_les_structures_culturelles.jpg',
+    alt: 'Partition tenue par une femme dans une chorale',
+    logoUrl: '/images/logos/opentalent/Logo_Opentalent_Artist-blanc.png',
+    logoAlt:
+      'Logo Opentalent Artist - logiciel de gestion et de communication pour les orchestres, les chorales, les compagnies artistiques et troupes',
+    class: 'artist',
+    link: '/opentalent_artist',
   },
   {
-    imageUrl: "/images/solutions/school.jpg",
-    logoUrl: "/images/logo/logiciels/School-Blanc.png",
-    class: "school",
-    link: "/opentalent_school",
+    imageUrl:
+      '/images/pages/qui-sommes-nous/logiciels/Opentalent_School_pour_les_etablissements_d_enseignement_artistique.JPG',
+    alt: 'Deux jeunes filles jouant du violon',
+    logoUrl: '/images/logos/opentalent/Logo_Opentalent_School-blanc.png',
+    logoAlt:
+      'Logo Opentalent School - logiciel de gestion et de communication pour les établissements d’enseignement artistique',
+    class: 'school',
+    link: '/opentalent_school',
   },
   {
-    imageUrl: "/images/solutions/manager.png",
-    logoUrl: "/images/logo/logiciels/Manager-Blanc.png",
-    class: "manager",
-    link: "/opentalent_manager",
+    imageUrl:
+      '/images/pages/qui-sommes-nous/logiciels/Opentalent_Manager_pour_les_reseaux_culturels.png',
+    alt: 'Carte de réseau des structures de la confédération musicale de France',
+    logoUrl: '/images/logos/opentalent/Logo_Opentalent_Manager-blanc.png',
+    logoAlt:
+      'Logo Opentalent Manager - logiciel de gestion et de communication pour les fédérations, les confédérations et les collectivités',
+    class: 'manager',
+    link: '/opentalent_manager',
   },
-];
+]
 </script>
 
 <style scoped lang="scss">
@@ -111,11 +121,11 @@ ul {
 li {
   margin-left: 0.8rem;
   position: relative;
-  margin-bottom: 10px;
+  margin-bottom: 6px;
 }
 
 li:before {
-  content: "";
+  content: '';
   position: absolute;
   left: -10px;
   top: 50%;
@@ -126,6 +136,12 @@ li:before {
   border-radius: 50%;
 }
 
+.software-link {
+  > .container-image:hover {
+    transform: scale(1.05);
+  }
+}
+
 .container-image {
   position: relative;
   background-repeat: no-repeat;
@@ -134,6 +150,7 @@ li:before {
   width: 100%;
   height: 370px;
   z-index: 0;
+  border-radius: 12px 12px 0 12px;
 
   footer {
     position: absolute;
@@ -154,24 +171,31 @@ li:before {
   }
 
   .plus-button {
-    width: 80px;
-    height: 80px;
+    width: 100px;
+    height: 100px;
     border-radius: 50% 0 0 0;
     background: var(--primary-color);
     color: var(--on-primary-color);
     box-shadow: none !important;
     border-top-left-radius: 10% !important;
+    margin-right: -10px;
+    margin-bottom: -10px;
 
     .v-icon {
       color: var(--on-primary-color);
       font-size: 2rem;
     }
   }
+}
 
-  :hover .plus-button {
-    transform: scale(1.2);
-    transition: all 0.3s ease-in-out;
-  }
+.container-image::after {
+  content: "";
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background: rgba(0, 0, 0, 0.4);
 }
 
 .artist .plus-button {

+ 81 - 52
components/About/Presentation.vue

@@ -1,64 +1,65 @@
 <template>
   <AnchoredSection id="about">
     <LayoutContainer>
-      <v-row class="mt-12 center-90">
-        <v-col cols="4">
-          <LayoutUISubTitle>
-            Qui sommes-nous ?
-          </LayoutUISubTitle>
+      <v-row class="my-4 center-90">
+        <v-col cols="12">
+          <LayoutUISubTitle> Qui sommes-nous ? </LayoutUISubTitle>
         </v-col>
+      </v-row>
 
-        <v-col cols="8">
-          <div class="italic-title mr-8">
-            “Imaginé par des musiciens pour des musiciens, Opentalent se veut être
-            la référence pour la gestion et la promotion du spectacle vivant sur
-            les territoires.”
+      <v-row class="my-6 center-90">
+        <v-col cols="12">
+          <div class="italic-title">
+            “Imaginé par des musiciens pour des musiciens, Opentalent se veut
+            être la référence pour la gestion et la promotion du spectacle
+            vivant sur les territoires.”
           </div>
         </v-col>
       </v-row>
 
       <v-row class="history mb-12">
-        <v-col cols="6">
-          <v-img src="/images/about/passion.jpg" cover />
+        <v-col cols="12" md="6">
+          <v-img
+            src="/images/pages/qui-sommes-nous/presentation/Concu_par_des_passiones_pour_des_passionnes.JPG"
+            alt="Entretien dans un bureau entre un homme et une femme de dos"
+            cover
+          />
         </v-col>
 
-        <v-col cols="6">
-          <h3>
-            Une histoire de passionnés
-          </h3>
+        <v-col cols="12" md="6">
+          <h3>Une histoire de passionnés</h3>
 
           <p class="mb-8">
-            En 2005, Guillaume CORCOBA, musicien depuis toujours et à ce moment
-            président d'un orchestre d'harmonie, mais également membre du conseil
-            d'administration de sa fédération, réfléchit à un outil pour
-            centraliser les informations de sa structure, mais également au niveau
-            fédéral. Il souhaite simplifier la gestion des structures culturelles
-            et en faire la promotion, car pour lui, le milieu culturel est
-            indispensable. Il est rapidement rejoint par Michel   PERNET-SOLLIET,
-            lui aussi musicien, et ils montent ensemble Openassos, qui deviendra
-            quelques années plus tard, Opentalent. Opentalent c'est un ensemble de
-            3 logiciels spécialement dédiés à la culture et un agenda culturel
-            pour en faire la promotion.
+            En 2005, Guillaume CORCOBA, musicien depuis toujours et à ce moment
+            président d'un orchestre d'harmonie, mais également membre du
+            conseil d'administration de sa fédération, réfléchit à un outil pour
+            centraliser les informations de sa structure, mais également au
+            niveau fédéral. Il souhaite simplifier la gestion des structures
+            culturelles et en faire la promotion, car pour lui, le milieu
+            culturel est indispensable. Il est rapidement rejoint par Michel
+            PERNET-SOLLIET, lui aussi musicien, et ils montent ensemble
+            Openassos, qui deviendra quelques années plus tard, Opentalent.
+            Opentalent c'est un ensemble de 3 logiciels spécialement dédiés à la
+            culture et un agenda culturel pour en faire la promotion.
           </p>
 
-          <h3>
-            La Culture au service du développement territorial
-          </h3>
+          <h3>La Culture au service du développement territorial</h3>
 
           <p>
-            Qui n'a jamais entendu que la culture coûtait trop cher ? On l'entend
-            , ha ça oui on l'a même trop entendu ! Mais la culture c'est avant
-            tout un facteur de lien social incroyable. On se retrouve, on échange,
-            on partage... on vit ensemble. On crée des vrais moments et on
-            développe des groupes de passionnés. On participe à rendre nos
-            collectivités attractives et surtout on les fait vivre, toute l'année,
-            à toutes les saisons. Depuis plusieurs décennies, un grand nombre de
-            territoires s'appuie sur le développement de la culture comme un outil
-            de développement territorial pour faire face à la
-            désindustrialisation, à une croissance démographique ralentie ou
-            encore une image défavorable. Ce modèle de développement par la
-            culture pour pallier un déficit d’attractivité touristique inspire de
-            plus en plus de politiques de développement territorial.
+            Qui n'a jamais entendu que la culture coûtait trop cher ? On
+            l'entend , ha ça oui on l'a même trop entendu ! Mais la culture
+            c'est avant tout un facteur de lien social incroyable. On se
+            retrouve, on échange, on partage... on vit ensemble. On crée des
+            vrais moments et on développe des groupes de passionnés. On
+            participe à rendre nos collectivités attractives et surtout on les
+            fait vivre, toute l'année, à toutes les saisons. Depuis plusieurs
+            décennies, un grand nombre de territoires s'appuie sur le
+            développement de la culture comme un outil de développement
+            territorial pour faire face à la désindustrialisation, à une
+            croissance démographique ralentie ou encore une image défavorable.
+            Ce modèle de développement par la culture pour pallier un déficit
+            d’attractivité touristique inspire de plus en plus de politiques de
+            développement territorial.
           </p>
         </v-col>
       </v-row>
@@ -67,20 +68,24 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
 </script>
 
 <style scoped lang="scss">
 .italic-title {
-  text-align: justify;
   font-style: italic;
   font-weight: 300;
   font-size: 34px;
   line-height: 40px;
   color: var(--primary-color);
   width: 80%;
-  margin-left: auto;
-  margin-bottom: auto;
+  margin: auto;
+
+  @media (max-width: 1240px) {
+    width: 90%;
+    margin-left: auto;
+    margin-right: auto;
+  }
 }
 
 .v-row.history {
@@ -88,12 +93,21 @@ import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
   margin-left: auto;
   margin-right: auto;
 
+  .v-col-12 {
+    padding: 16px 5%;
+  }
+
   .v-img {
     background-repeat: no-repeat;
     background-position: center;
-    width: 400px;
+    width: 100%;
     height: 100%;
     border-radius: 20px;
+    margin: 0 auto;
+
+    @media (max-width: 600px) {
+      width: 90%;
+    }
   }
 
   h3 {
@@ -112,17 +126,32 @@ import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
     margin-bottom: 3rem;
     width: 25rem;
     text-align: justify;
+
+    @media (max-width: 600px) {
+      width: 100%;
+    }
   }
 
   p {
-    text-align: justify;
     font-weight: 300;
     font-size: 16px;
     line-height: 20px;
-    width: 30rem;
     margin-bottom: 2rem;
-  }
-}
 
+    @media (max-width: 600px) {
+      width: 100%;
+    }
+  }
 
+  @media (max-width: 1240px) {
+    h3,
+    h4,
+    p,
+    .v-img {
+      width: 100%;
+      margin-left: auto;
+      margin-right: auto;
+    }
+  }
+}
 </style>

+ 53 - 30
components/About/Valeurs.vue

@@ -2,36 +2,35 @@
   <AnchoredSection id="values">
     <LayoutContainer class="mt-12">
       <v-row class="center-90">
-        <LayoutUISubTitle>
-          Les valeurs qui nous portent
-        </LayoutUISubTitle>
+        <LayoutUISubTitle> Les valeurs qui nous portent </LayoutUISubTitle>
       </v-row>
 
       <v-row class="mt-6 center-90 align-center mb-12">
-        <v-col cols="6">
+        <v-col cols="12" lg="6">
           <v-img
-            src="/images/about/valeurs/valeur.png"
+            src="/images/pages/qui-sommes-nous/valeurs/Opentalent_les_valeurs_qui_nous_portent.png"
+            alt="Quatre photos: une prise de haut où l’on voit les pieds d’une personne avec un smiley dessiné sur du goudron, l'une de mains tenant de la terre avec une plante dans un décor de forêt, l'une d’une enseigne lumineuse écrit « Open » en blanc entouré d’un cercle orange et l'une de mains de femmes posées les unes en dessus des autres."
             cover
             class="valeur-img"
           />
         </v-col>
 
-        <v-col cols="6">
+        <v-col cols="12" lg="6">
           <div class="values">
-            <v-row
-              v-for="(row, rowIndex) in values"
-              :key="rowIndex"
-            >
+            <v-row v-for="(row, rowIndex) in values" :key="rowIndex">
               <v-col
-                cols="6"
                 v-for="(value, valueIndex) in row"
                 :key="valueIndex"
+                cols="12"
+                md="6"
               >
-                <v-img :src="value.img" cover />
+                <div class="d-flex flex-row align-center">
+                  <v-img :src="value.img" :alt="value.alt" cover class="mr-3" />
 
-                <h6>
-                  {{ value.title }}
-                </h6>
+                  <h6>
+                    {{ value.title }}
+                  </h6>
+                </div>
 
                 <p>
                   {{ value.description }}
@@ -46,39 +45,43 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { SocietyValue } from "~/types/interface";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { SocietyValue } from '~/types/interface'
 
 const values: Array<Array<SocietyValue>> = [
   [
     {
-      img: "/images/about/valeurs/Management.svg",
-      title: "Management social",
+      img: '/images/pages/qui-sommes-nous/valeurs/Management.svg',
+      alt: 'Icône management social',
+      title: 'Management social',
       description:
         "Guillaume et Michel sont sur la même longueur d’onde et donnent le « La » à un management social et solidaire où plus que de mettre en avant l'entreprise, ils privilégient la mise en avant des hommes et femmes qui la composent. Toux ceux qui participent jour après jour à l’écriture de la partition sont valorisés. Le partage, l’échange et le dialogue en lieu et place des liens de subordination.",
     },
     {
-      img: "/images/about/valeurs/Satisfaction-client.svg",
-      title: "Satisfaction client",
+      img: '/images/pages/qui-sommes-nous/valeurs/Satisfaction-client.svg',
+      alt: 'Icône Satisfaction client',
+      title: 'Satisfaction client',
       description:
-        "Opentalent met un point d’honneur à satisfaire ses clients en leur proposant des solutions de qualité, un projet global dans lequel ils se retrouvent. L’intention de base est bel et bien de proposer un équilibre entre les solutions informatiques et la volonté personnelle en lien avec la production et les publics concernés.",
+        'Opentalent met un point d’honneur à satisfaire ses clients en leur proposant des solutions de qualité, un projet global dans lequel ils se retrouvent. L’intention de base est bel et bien de proposer un équilibre entre les solutions informatiques et la volonté personnelle en lien avec la production et les publics concernés.',
     },
   ],
   [
     {
-      img: "/images/about/valeurs/Ecologie.svg",
-      title: "Écologie",
+      img: '/images/pages/qui-sommes-nous/valeurs/Ecologie.svg',
+      alt: 'Icône Écologie',
+      title: 'Écologie',
       description:
-        "Proche des entreprises de l’Économie Sociale et Solidaire, Opentalent accorde une grande importance aux démarches liées à l’écologie et au développement durable. Le code des outils est par exemple optimisé pour limiter les ressources nécessaires des serveurs, réduisant ainsi leur empreinte carbone et améliorant le confort des utilisateurs au quotidien.",
+        'Proche des entreprises de l’Économie Sociale et Solidaire, Opentalent accorde une grande importance aux démarches liées à l’écologie et au développement durable. Le code des outils est par exemple optimisé pour limiter les ressources nécessaires des serveurs, réduisant ainsi leur empreinte carbone et améliorant le confort des utilisateurs au quotidien.',
     },
     {
-      img: "/images/about/valeurs/Open-source.svg",
-      title: "Open source",
+      img: '/images/pages/qui-sommes-nous/valeurs/Open-source.svg',
+      alt: 'Icône Open source',
+      title: 'Open source',
       description:
-        "Opentalent est une entreprise qui croit profondément aux vertus des logiciels Open Source et qui par son action contribue à leur développement.",
+        'Opentalent est une entreprise qui croit profondément aux vertus des logiciels Open Source et qui par son action contribue à leur développement.',
     },
   ],
-];
+]
 </script>
 
 <style scoped lang="scss">
@@ -87,17 +90,31 @@ const values: Array<Array<SocietyValue>> = [
   background-position: center;
   height: 400px;
   width: 450px;
+  margin-left: auto;
+  margin-right: auto;
+
+  @media (max-width: 1240px) {
+    width: 90%;
+  }
 }
 
 .values {
   .v-row {
-    border-top: 1px solid var(--on-neutral-color-extra-light);
+    @media (min-width: 1240px) {
+      border-top: 1px solid var(--on-neutral-color-extra-light);
+    }
   }
 
   .v-img {
     width: 50px;
+    max-width: 50px;
     height: 50px;
     margin-bottom: 1rem;
+
+    @media (max-width: 600px) {
+      margin-left: 0;
+      margin-right: auto;
+    }
   }
 
   h6 {
@@ -107,5 +124,11 @@ const values: Array<Array<SocietyValue>> = [
     color: var(--primary-color);
     margin-bottom: 1rem;
   }
+
+  @media (max-width: 1240px) {
+    width: 90%;
+    margin-left: auto;
+    margin-right: auto;
+  }
 }
 </style>

+ 55 - 39
components/Common/ActionMenu.vue

@@ -4,7 +4,7 @@ de l'écran (ou au bas de l'écran sur les petits écrans)
 -->
 <template>
   <!-- Écrans larges : menu lateral, accroché au bord droit de l'écran -->
-  <div class="sticky-menu lateral" v-if="lgAndUp && isVisible">
+  <div v-if="lgAndUp && isVisible" class="sticky-menu lateral">
     <v-row
       v-for="(action, index) in actionsOrDefault"
       :key="index"
@@ -13,9 +13,7 @@ de l'écran (ou au bas de l'écran sur les petits écrans)
     >
       <NuxtLink :to="action.url" class="link">
         <div>
-          <v-icon
-            :class="action.icon"
-          />
+          <v-icon :class="action.icon" />
 
           <p class="text-square mt-2">
             {{ action.text }}
@@ -26,7 +24,15 @@ de l'écran (ou au bas de l'écran sur les petits écrans)
   </div>
 
   <!-- Petits écrans : menu sous forme de bandeau en pied de page (sauf si le footer du site est visible) -->
-  <div class="sticky-menu band" v-else-if="isVisible">
+  <div v-else-if="isVisible" class="sticky-menu band">
+    <v-btn
+      :to="{ path: '', hash: '#top' }"
+      class="primary"
+      :width="24"
+    >
+      <v-icon>fas fa-arrow-up</v-icon>
+    </v-btn>
+
     <v-btn
       v-for="(action, index) in actionsOrDefault"
       :key="index"
@@ -39,39 +45,43 @@ de l'écran (ou au bas de l'écran sur les petits écrans)
 </template>
 
 <script setup lang="ts">
-import { useRouter } from "vue-router";
-import { useDisplay } from "vuetify";
-import { useLayoutStore } from "~/stores/layoutStore";
-import { ActionMenuItemType } from "~/types/enum/layout";
-import type { ActionMenuItem } from "~/types/interface";
-
-const { lgAndUp } = useDisplay();
-const router = useRouter();
+import { useRouter } from 'vue-router'
+import { useDisplay } from 'vuetify'
+import type { ComputedRef } from 'vue'
+import { useLayoutStore } from '~/stores/layoutStore'
+import { ActionMenuItemType } from '~/types/enum/layout'
+import type { ActionMenuItem } from '~/types/interface'
+
+const { lgAndUp } = useDisplay()
+const router = useRouter()
 const layoutStore = useLayoutStore()
 const { isMobileDevice } = useClientDevice()
 
-const telephoneNumber = "09 72 12 60 17";
+const telephoneNumber = '09 72 12 60 17'
 
-const isVisible: ComputedRef<boolean> = computed(() =>
-  !layoutStore.isHeaderVisible && !layoutStore.isFooterVisible
+const isVisible: ComputedRef<boolean> = computed(
+  () =>
+    !layoutStore.isHeaderVisible &&
+    !layoutStore.isBannerVisible &&
+    !layoutStore.isFooterVisible
 )
 
 // Actions par défaut du menu, peut-être surchargé via la propriété `actions`
 const defaultActions: Array<ActionMenuItem> = [
   {
     type: ActionMenuItemType.FOLLOW_LINK,
-    color: "secondary",
-    icon: "far fa-comments",
-    text: "Nous contacter",
-    url: "/nous-contacter",
+    color: 'secondary',
+    icon: 'far fa-comments',
+    text: 'Nous contacter',
+    url: { path: 'nous-contacter', hash: '#form' },
   },
   {
     type: ActionMenuItemType.CALL_US,
-    color: "primary",
-    icon: "fas fa-phone",
-    text: "Nous Appeler",
+    color: 'primary',
+    icon: 'fas fa-phone',
+    text: 'Nous Appeler',
   },
-];
+]
 
 const props = defineProps({
   /**
@@ -80,8 +90,8 @@ const props = defineProps({
   actions: {
     type: Array<ActionMenuItem>,
     required: false,
-    default: []
-  }
+    default: [],
+  },
 })
 
 const actionsOrDefault: ComputedRef<Array<ActionMenuItem>> = computed(() => {
@@ -90,9 +100,9 @@ const actionsOrDefault: ComputedRef<Array<ActionMenuItem>> = computed(() => {
 
 const callUs = () => {
   if (isMobileDevice()) {
-    window.location.href = `tel:${telephoneNumber}`;
+    window.location.href = `tel:${telephoneNumber}`
   } else {
-    alert(`Notre numéro de téléphone : ${telephoneNumber}`);
+    navigateTo({ path: 'nous-contacter', hash: '#details' })
   }
 }
 
@@ -103,35 +113,34 @@ const callUs = () => {
 const onActionClick = (action: ActionMenuItem) => {
   switch (action.type) {
     case ActionMenuItemType.ASK_FOR_A_DEMO:
-      router.push({ path: action.url, query: { request: "demo" } });
-      break;
+      router.push({ path: action.url as string, query: { request: 'demo' } })
+      break
 
     case ActionMenuItemType.CALL_US:
       callUs()
-      break;
+      break
 
     case ActionMenuItemType.FOLLOW_LINK:
       if (!action.url) {
-        throw Error('Missing prop : url')
+        throw new Error('Missing prop : url')
       }
-      router.push({ path: action.url });
+      navigateTo(action.url)
       break
 
     default:
-      throw Error('Unrecognized action')
+      throw new Error('Unrecognized action')
   }
-};
+}
 </script>
 
 <style scoped lang="scss">
-
 .sticky-menu {
   z-index: 100;
 }
 
 // Menu format lateral (pour affichage écrans larges)
 .sticky-menu.lateral {
-  position: sticky;
+  position: fixed;
   right: 0;
   top: 60%;
   transform: translateY(-50%);
@@ -143,7 +152,7 @@ const onActionClick = (action: ActionMenuItem) => {
   font-weight: 500;
   font-size: 0.7rem;
   line-height: 15px;
-  text-align: center;
+  text-align: center !important;
   letter-spacing: 0.2em;
   text-transform: uppercase;
 }
@@ -157,9 +166,11 @@ const onActionClick = (action: ActionMenuItem) => {
   display: flex;
   justify-content: center;
   background-color: var(--neutral-color);
+  max-width: 100vw;
+  padding: 0 6px;
 
   .v-btn {
-    margin: 4px 6px;
+    margin: 6px 2%;
   }
 }
 
@@ -170,6 +181,7 @@ const onActionClick = (action: ActionMenuItem) => {
   cursor: pointer;
 
   transition: transform 0.3s ease-in-out;
+  box-shadow: -1px 2px 6px 1px var(--on-neutral-color-light);
 }
 
 .square:hover {
@@ -179,6 +191,10 @@ const onActionClick = (action: ActionMenuItem) => {
 .link {
   text-decoration: none;
   color: var(--on-primary-color);
+
+  * {
+    text-align: center;
+  }
 }
 
 .primary {

+ 61 - 76
components/Common/Agenda.vue

@@ -3,32 +3,22 @@ Section "Agenda des évènements"
 -->
 <template>
   <AnchoredSection id="agenda">
-    <LayoutContainer class="mb-12" >
+    <LayoutContainer class="mb-12">
       <v-row class="center-90 align-center my-6">
         <v-col cols="4" class="align-center">
-          <LayoutUITitle>
-            L'agenda Opentalent
-          </LayoutUITitle>
+          <LayoutUITitle> L'agenda Opentalent </LayoutUITitle>
         </v-col>
 
         <v-col cols="4">
           <!-- Factoriser les contrôles du carousel dans un component -->
           <div class="carousel-controls">
-            <v-btn
-              icon="fas fa-chevron-left"
-              @click="goPrevious"
-            />
-            <v-btn
-              icon="fas fa-chevron-right"
-              @click="goNext"
-            />
+            <v-btn icon="fas fa-chevron-left" @click="goPrevious" />
+            <v-btn icon="fas fa-chevron-right" @click="goNext" />
           </div>
         </v-col>
 
         <v-col cols="4" class="d-flex flex-row flex-1 justify-end align-center">
-          <v-btn class="btn-news" text>
-            Voir tous les évènements
-          </v-btn>
+          <v-btn class="btn-news" text> Voir tous les évènements </v-btn>
         </v-col>
       </v-row>
 
@@ -40,11 +30,7 @@ Section "Agenda des évènements"
 
       <v-row class="center-90">
         <v-col cols="12">
-          <Carousel
-            ref="carousel"
-            :items-to-show="3"
-            :items-to-scroll="2"
-          >
+          <Carousel ref="carousel" :items-to-show="3" :items-to-scroll="2">
             <Slide
               v-for="(event, eventIndex) in events"
               :key="eventIndex"
@@ -69,9 +55,7 @@ Section "Agenda des évènements"
                       :color="tagColor(tag)"
                       label
                     >
-                      <span
-                        :class="tagTextColor(tag)"
-                      >
+                      <span :class="tagTextColor(tag)">
                         {{ tag }}
                       </span>
                     </v-chip>
@@ -87,88 +71,89 @@ Section "Agenda des évènements"
 </template>
 
 <script setup lang="ts">
-import { Carousel, Slide } from "vue3-carousel";
-import "vue3-carousel/dist/carousel.css";
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { Event } from "~/types/interface";
+import { Carousel, Slide } from 'vue3-carousel'
+import 'vue3-carousel/dist/carousel.css'
+import type { Ref } from 'vue'
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { Event } from '~/types/interface'
 
 const tagColor = (tag: string) => {
   switch (tag) {
-    case "Payant":
-      return "red";
-    case "Gratuit":
-      return "green";
+    case 'Payant':
+      return 'red'
+    case 'Gratuit':
+      return 'green'
     default:
-      return "primary";
+      return 'primary'
   }
-};
+}
 
 const tagTextColor = (tag: string) => {
   switch (tag) {
-    case "Payant":
-      return "red--text";
-    case "Gratuit":
-      return "green--text";
+    case 'Payant':
+      return 'red--text'
+    case 'Gratuit':
+      return 'green--text'
     default:
-      return "black--text";
+      return 'black--text'
   }
-};
+}
 
 const events: Array<Event> = [
   {
-    rdv: "20h00",
-    title: "LA NUIT DES RÊVES  ",
-    localisation: "FESTIVALDE musique - LONGCHAMP",
-    date: "21/06/2023",
-    img: "/images/agenda/agenda2.jpg",
-    tags: ["Festival", "Musique", "Tout public", "Payant"],
+    rdv: '20h00',
+    title: 'LA NUIT DES RÊVES  ',
+    localisation: 'FESTIVALDE musique - LONGCHAMP',
+    date: '21/06/2023',
+    img: '/images/agenda/agenda2.jpg',
+    tags: ['Festival', 'Musique', 'Tout public', 'Payant'],
   },
   {
-    rdv: "20h00",
-    title: "LE LAC DES CYGNES",
-    localisation: "SPECTACLE DE DANSE - PARIS 1",
-    date: "22/06/2023",
-    img: "/images/agenda/agenda3.jpg",
-    tags: ["Festival", "Musique", "Tout public", "Gratuit"],
+    rdv: '20h00',
+    title: 'LE LAC DES CYGNES',
+    localisation: 'SPECTACLE DE DANSE - PARIS 1',
+    date: '22/06/2023',
+    img: '/images/agenda/agenda3.jpg',
+    tags: ['Festival', 'Musique', 'Tout public', 'Gratuit'],
   },
   {
-    rdv: "20h00",
-    title: "SOLIDAYS 2023  : 23 > 25 juin",
-    localisation: "ORCHESTRE DE PARIS - PARIS 12",
-    date: "23/06/2023",
-    img: "/images/agenda/agenda4.jpg",
-    tags: ["Festival", "Musique", "Tout public", "Payant"],
+    rdv: '20h00',
+    title: 'SOLIDAYS 2023  : 23 > 25 juin',
+    localisation: 'ORCHESTRE DE PARIS - PARIS 12',
+    date: '23/06/2023',
+    img: '/images/agenda/agenda4.jpg',
+    tags: ['Festival', 'Musique', 'Tout public', 'Payant'],
   },
   {
-    rdv: "20h00",
-    title: "LE LAC DES CYGNES",
-    localisation: "FESTIVALDE musique - LONGCHAMP",
-    date: "24/06/2023",
-    img: "/images/agenda/agenda5.jpg",
-    tags: ["Festival", "Musique", "Tout public", "Payant"],
+    rdv: '20h00',
+    title: 'LE LAC DES CYGNES',
+    localisation: 'FESTIVALDE musique - LONGCHAMP',
+    date: '24/06/2023',
+    img: '/images/agenda/agenda5.jpg',
+    tags: ['Festival', 'Musique', 'Tout public', 'Payant'],
   },
   {
-    rdv: "20h00",
-    title: "SOLIDAYS 2023  : 23 > 25 juin ",
-    localisation: "SPECTACLE DE DANSE - PARIS 1",
-    date: "20/06/2023",
-    img: "/images/agenda/agenda1.jpg",
-    tags: ["Festival", "Musique", "Tout public", "Payant"],
+    rdv: '20h00',
+    title: 'SOLIDAYS 2023  : 23 > 25 juin ',
+    localisation: 'SPECTACLE DE DANSE - PARIS 1',
+    date: '20/06/2023',
+    img: '/images/agenda/agenda1.jpg',
+    tags: ['Festival', 'Musique', 'Tout public', 'Payant'],
   },
-];
+]
 
-const carousel: Ref<typeof Carousel | null> = ref(null);
+const carousel: Ref<typeof Carousel | null> = ref(null)
 
-const goPrevious = () => carousel.value!.prev();
-const goNext = () => carousel.value!.next();
+const goPrevious = () => carousel.value!.prev()
+const goNext = () => carousel.value!.next()
 </script>
 
 <style scoped>
-.v-container{
+.v-container {
   padding: 0 !important;
 }
 
-.container{
+.container {
   background: var(--neutral-color);
 }
 
@@ -226,7 +211,7 @@ const goNext = () => carousel.value!.next();
     }
   }
 
-  footer{
+  footer {
     display: flex;
     text-align: left !important;
 

+ 9 - 7
components/Common/AgendaLink.vue

@@ -5,21 +5,23 @@
 </template>
 
 <script setup lang="ts">
-import UrlUtils from "~/services/utils/urlUtils";
+import UrlUtils from '~/services/utils/urlUtils'
 
 const runtimeConfig = useRuntimeConfig()
 
 const props = defineProps({
   href: {
-    type: String
-  }
+    type: String,
+    required: true,
+  },
 })
 
 const target = computed(() => {
-  return UrlUtils.join(runtimeConfig.public.agendaBaseUrl as string, props.href as string)
+  return UrlUtils.join(
+    runtimeConfig.public.agendaBaseUrl as string,
+    props.href as string
+  )
 })
 </script>
 
-<style scoped lang="scss">
-
-</style>
+<style scoped lang="scss"></style>

+ 9 - 16
components/Common/Avantages.vue

@@ -10,35 +10,28 @@
       </LayoutUITitle>
     </v-row>
 
-    <v-row class="center-90">
-      <v-col
-        cols="12"
-        md="4"
-        offset-md="1"
-        v-for="(benefit, index) in benefits"
-        :key="index"
-      >
-        <CommonCardBenefit
-          :benefit="benefit"
-        />
+    <v-row class="center-90 benefits">
+      <v-col v-for="(benefit, index) in benefits" :key="index" cols="12" md="4">
+        <CommonCardBenefit :benefit="benefit" />
       </v-col>
     </v-row>
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-import type { Benefit } from "~/types/interface";
+import type { PropType } from 'vue'
+import type { Benefit } from '~/types/interface'
 
-const props = defineProps({
+defineProps({
   benefits: {
     type: Array as PropType<Array<Benefit>>,
-    required: true
+    required: true,
   },
   title: {
     type: String,
     required: false,
-    default: "Des avantages concrets"
-  }
+    default: 'Des avantages concrets',
+  },
 })
 </script>
 

+ 46 - 16
components/Common/Banner.vue

@@ -1,5 +1,5 @@
 <template>
-  <LayoutContainer>
+  <LayoutContainer v-intersect="onIntersect">
     <v-row>
       <v-col cols="12">
         <div class="banner-container">
@@ -13,8 +13,8 @@
             <v-row>
               <div class="content-row">
                 <img
-                  src="/images/logiciels/icons/la-musique.svg"
-                  alt="icon instrument de musique"
+                  src="/images/components/banner/Icone_instruments_de_musique_trompette_et_tambour_avec_des_notes_de_musique.svg"
+                  alt="Icône instruments de musique trompette et tambour avec des notes de musique"
                   class="custom-icon"
                 />
                 <p class="description">
@@ -24,8 +24,11 @@
             </v-row>
           </div>
 
-          <div v-if="logoSrc" :class="'logo-square' + (logoAltTheme ? ' alt-theme' : '')">
-            <img :src="logoSrc" :alt="logoAlt"/>
+          <div
+            v-if="logoSrc"
+            :class="'logo-square' + (logoAltTheme ? ' alt-theme' : '')"
+          >
+            <img :src="logoSrc" :alt="logoAlt" />
           </div>
 
           <div class="image-text mt-12">
@@ -38,45 +41,55 @@
 </template>
 
 <script setup lang="ts">
+import type { PropType } from 'vue'
+import { useLayoutStore } from '~/stores/layoutStore'
 
-const props = defineProps({
+defineProps({
   imageSrc: {
     type: String,
-    required: true
+    required: true,
   },
   imageAlt: {
     type: String,
-    default: ""
+    default: '',
   },
   squareText: {
     type: String,
-    default: "École de musique, d'art, de danse, de cirque, conservatoires et MJC"
+    default:
+      "École de musique, d'art, de danse, de cirque, conservatoires et MJC",
   },
   logoSrc: {
     type: String as PropType<string | null>,
     required: false,
-    default: null
+    default: null,
   },
   logoAlt: {
     type: String,
     required: false,
-    default: ""
+    default: '',
   },
   logoAltTheme: {
     type: Boolean,
-    default: false
+    default: false,
   },
   reverseImage: {
     type: Boolean,
-    default: false
-  }
-});
+    default: false,
+  },
+})
+
+const layoutStore = useLayoutStore()
+const onIntersect = (isIntersecting: boolean) => {
+  layoutStore.setIsBannerVisible(isIntersecting)
+}
 </script>
 
 <style scoped lang="scss">
 .banner-container {
   position: relative;
   overflow: hidden;
+  min-height: 400px;
+  max-height: 400px;
 
   .image-text {
     position: absolute;
@@ -89,6 +102,10 @@ const props = defineProps({
     font-weight: 300;
     line-height: 40px;
   }
+
+  @media (max-width: 600px) {
+    min-height: 0;
+  }
 }
 
 .cover-image {
@@ -99,6 +116,10 @@ const props = defineProps({
   object-position: center var(--banner-center-image);
   transition: transform 0.2s;
   margin: 0 auto;
+
+  @media (max-width: 600px) {
+    min-height: 0;
+  }
 }
 
 .reverse {
@@ -108,7 +129,7 @@ const props = defineProps({
 .custom-icon {
   width: 3rem;
   height: 3rem;
-  margin-top: .5rem;
+  margin-top: 0.5rem;
 }
 
 .details-square {
@@ -118,6 +139,10 @@ const props = defineProps({
   width: 13rem;
   height: 10rem;
   background: var(--secondary-color);
+
+  @media (max-width: 600px) {
+    width: 50%;
+  }
 }
 
 .logo-square {
@@ -132,6 +157,11 @@ const props = defineProps({
     height: 50%;
     margin-top: 2.5rem;
   }
+
+  @media (max-width: 600px) {
+    right: 50%;
+    width: 50%;
+  }
 }
 .logo-square:not(.alt-theme) {
   background: var(--primary-color);

+ 8 - 10
components/Common/Card/Benefit.vue

@@ -14,7 +14,7 @@ Carte "Avantage" de la section Avantages d'une page Logiciel
         </span>
       </div>
 
-      <v-divider thickness="2"/>
+      <v-divider thickness="1" />
 
       <div class="description">
         <p class="mr-4">
@@ -22,23 +22,21 @@ Carte "Avantage" de la section Avantages d'une page Logiciel
         </p>
       </div>
 
-      <v-img
-        :src="benefit.image"
-        cover
-      />
+      <v-img :src="benefit.image" :alt="benefit.alt" cover />
     </div>
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-import type { Benefit } from "~/types/interface";
+import type { PropType } from 'vue'
+import type { Benefit } from '~/types/interface'
 
-const props = defineProps({
+defineProps({
   benefit: {
     type: Object as PropType<Benefit>,
-    required: true
-  }
-});
+    required: true,
+  },
+})
 </script>
 
 <style scoped lang="scss">

+ 14 - 6
components/Common/Card/Stat.vue

@@ -12,12 +12,14 @@
 <script setup lang="ts">
 const props = defineProps({
   number: {
-    type: String
+    type: String,
+    required: true,
   },
   text: {
-    type: String
+    type: String,
+    required: true,
   },
-});
+})
 </script>
 
 <style scoped lang="scss">
@@ -33,14 +35,20 @@ const props = defineProps({
   align-items: center;
   text-align: center;
 
-  p:first-child{
+  p:first-child {
     font-weight: 600;
     font-size: 60px;
     line-height: 68px;
     text-align: center;
     margin-bottom: 0.5rem;
-  }
-}
 
+    @media (max-width: 1600px) {
+      font-size: 48px;
+    }
+  }
 
+  @media (max-width: 1240px) {
+    height: 12rem;
+  }
+}
 </style>

+ 46 - 22
components/Common/Carousel/Clients.vue

@@ -6,7 +6,8 @@
     <v-row justify="center">
       <h3 class="text-center">
         <slot name="title">
-          Plus de <span class="alt-color">5000 structures</span> nous font confiance
+          Plus de <span class="alt-color">5000 structures</span> nous font
+          confiance
         </slot>
       </h3>
     </v-row>
@@ -15,6 +16,7 @@
       <v-row>
         <!-- Fléche de gauche -->
         <v-btn
+          v-if="lgAndUp"
           icon="fas fa-chevron-left"
           @click="goToPrevious"
         />
@@ -23,46 +25,52 @@
         <Carousel
           ref="carousel"
           class="elevation-4 mb-12"
-          :items-to-show="4"
-          :items-to-scroll="2"
+          :items-to-show="smAndUp ? 4 : 1"
+          :items-to-scroll="smAndUp ? 2 : 1"
+          :wrap-around="true"
         >
-          <Slide v-for="(item, index) in items" :key="index">
+          <Slide v-for="item in items" :key="item.src">
             <div>
-              <v-img :src="item.src" alt="Card image cap" />
+              <v-img :src="item.src" :alt="item.alt" />
             </div>
           </Slide>
         </Carousel>
 
         <!-- Fléche de droite -->
-        <v-btn
-          icon="fas fa-chevron-right"
-          @click="goToNext"
-        />
+        <v-btn v-if="lgAndUp" icon="fas fa-chevron-right" @click="goToNext" />
+      </v-row>
+
+      <v-row v-if="mdAndDown">
+        <v-btn icon="fas fa-chevron-left" @click="goToPrevious" />
+        <v-btn icon="fas fa-chevron-right" @click="goToNext" />
       </v-row>
     </v-container>
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-import { Carousel, Slide } from "vue3-carousel";
-import type { PropType } from "@vue/runtime-core";
+import { Carousel, Slide } from 'vue3-carousel'
+import type { PropType, Ref } from 'vue'
+import { useDisplay } from 'vuetify'
 
-const carousel: Ref<typeof Carousel | null> = ref(null);
+const { smAndUp, lgAndUp, mdAndDown } = useDisplay()
 
-const props = defineProps({
+const carousel: Ref<typeof Carousel | null> = ref(null)
+
+defineProps({
   items: {
-    type: Array as PropType<Array<{ src: string }>>,
-    required: true
-  }
-});
+    type: Array as PropType<Array<{ src: string; alt: string }>>,
+    required: true,
+  },
+})
 
 const goToPrevious = () => {
-  carousel.value!.prev();
-};
+  carousel.value!.prev()
+}
 
 const goToNext = () => {
-  carousel.value!.next();
-};
+  carousel.value!.next()
+}
 </script>
 
 <style scoped lang="scss">
@@ -83,10 +91,14 @@ h3 {
   line-height: 42px;
   color: var(--on-primary-color);
   width: 50%;
+
+  @media (max-width: 1240px) {
+    width: 70%;
+  }
 }
 
 .alt-color {
-  color: var(--on-primary-color-alt);
+  color: var(--on-primary-color-alt) !important;
 }
 
 .v-btn {
@@ -106,12 +118,24 @@ h3 {
 }
 
 .carousel {
+  width: 960px;
+  height: 240px;
   background-color: var(--neutral-color);
   margin-top: 2rem;
   border-radius: 20px;
   margin-left: auto;
   margin-right: auto;
   box-shadow: var(--primary-color);
+
+  @media (max-width: 1240px) {
+    width: 50%;
+    min-width: 600px;
+  }
+
+  @media (max-width: 1240px) {
+    width: 90%;
+    min-width: 90%;
+  }
 }
 
 .v-img {

+ 57 - 48
components/Common/Carousel/Fonctionnalite.vue

@@ -1,7 +1,7 @@
 <template>
   <LayoutContainer>
-    <v-row>
-      <v-col cols="6">
+    <v-row class="center-90">
+      <v-col cols="12" md="6">
         <LayoutUISubTitle>
           Découvrez toutes les fonctionnalités de notre solution
         </LayoutUISubTitle>
@@ -11,28 +11,24 @@
         </LayoutUITitle>
       </v-col>
 
-      <v-col cols="12" md="6" class="d-flex align-center justify-start">
+      <v-col cols="12" md="6" class="arrows">
         <v-btn icon="fas fa-chevron-left" @click="previousAction" />
         <v-btn icon="fas fa-chevron-right" @click="nextAction" />
       </v-col>
     </v-row>
 
     <v-row>
-      <v-col cols="12" md="12">
+      <v-col cols="12">
         <Carousel
           ref="carousel"
-          :items-to-show="4"
+          :items-to-show="itemsToShow"
           :items-to-scroll="1"
           :wrap-around="true"
         >
-          <Slide v-for="(card, index) in cards" :key="index" >
+          <Slide v-for="(card, index) in cards" :key="index">
             <div class="card-container">
               <v-card class="inv-theme">
-                <v-img
-                  :src="card.logo"
-                  :alt="card.title"
-                  class="mx-auto"
-                />
+                <v-img :src="card.logo" :alt="card.title" class="mx-auto" />
 
                 <v-card-title>
                   <h5>
@@ -43,24 +39,18 @@
                 <v-card-item>
                   <v-card-text>
                     <ul>
-                      <li
-                        v-for="item in card.list"
-                        :key="item"
-                      >
+                      <li v-for="item in card.list" :key="item">
                         <p>{{ item }}</p>
                       </li>
                     </ul>
                   </v-card-text>
-
                 </v-card-item>
+
                 <div class="footer">
-                    <p
-                      v-for="option in card.options"
-                      :key="option"
-                    >
-                      {{ option }}
-                    </p>
-                  </div>
+                  <p v-for="option in card.options" :key="option">
+                    {{ option }}
+                  </p>
+                </div>
               </v-card>
             </div>
           </Slide>
@@ -71,33 +61,41 @@
 </template>
 
 <script setup lang="ts">
-import { useDisplay } from "vuetify";
-import { Carousel, Slide } from "vue3-carousel";
-import "vue3-carousel/dist/carousel.css";
-import type { PropType } from "@vue/runtime-core";
-import type { Functionality } from "~/types/interface";
+import { useDisplay } from 'vuetify'
+import { Carousel, Slide } from 'vue3-carousel'
+import 'vue3-carousel/dist/carousel.css'
+import type { PropType, Ref } from 'vue'
+import type { Functionality } from '~/types/interface'
 
-const { mdAndDown } = useDisplay();
+const { lgAndUp, mdAndUp, smAndUp } = useDisplay()
 
-const props = defineProps({
+defineProps({
   cards: {
     type: Array as PropType<Array<Functionality>>,
-    required: true
-  }
+    required: true,
+  },
 })
 
-const carousel: Ref<typeof Carousel | null> = ref(null);
+const carousel: Ref<typeof Carousel | null> = ref(null)
+
+const itemsToShow = computed(() =>
+  lgAndUp.value ? 5 : mdAndUp.value ? 3 : smAndUp.value ? 2 : 1
+)
 
 const nextAction = () => {
-  carousel.value!.next();
-};
+  carousel.value!.next()
+}
 
 const previousAction = () => {
-  carousel.value!.prev();
-};
+  carousel.value!.prev()
+}
 </script>
 
 <style scoped lang="scss">
+h5 {
+  text-align: center;
+}
+
 .v-row {
   width: 95%;
   margin-left: auto;
@@ -119,26 +117,32 @@ const previousAction = () => {
 .carousel {
   margin-left: 2rem;
   margin-right: 2rem;
+  margin-bottom: 2rem;
 }
 
 .card-container {
   display: flex;
   justify-content: center;
   align-items: center;
-  margin-bottom: 3rem;
   margin-right: 2rem;
+  width: 100%;
+  height: 100%;
 }
 
 .v-card {
   border-radius: 1rem;
   transition: transform 0.3s;
   font-weight: 300;
-  min-height: 25rem !important;
+  width: 100%;
+  height: 100%;
+  padding: 0 10% 14px 10%;
 
   .v-img {
     width: 5rem;
     height: 3rem;
     margin-top: 1rem;
+    margin-bottom: 12px;
+    fill: #fac20a !important;
   }
 
   .v-card-title {
@@ -160,19 +164,24 @@ const previousAction = () => {
   .footer {
     position: absolute;
     left: 0;
-    margin-left: .5rem;
-    font-size: .9rem;
+    bottom: 1rem;
+    margin-left: 1.3rem;
+    font-size: 0.9rem;
+
+    p {
+      text-align: left;
+    }
   }
 }
 
-@media(min-width: 1800px){
-  .v-card{
-    min-height: 400px !important;
-    max-height: 400px !important;
-    min-width: 400px !important;
-    max-width: 400px !important;
+.arrows {
+  display: flex;
+  align-content: center;
+  justify-content: end;
+
+  @media (max-width: 600px) {
+    justify-content: center;
   }
 }
 
-
 </style>

+ 170 - 0
components/Common/Contact.vue

@@ -0,0 +1,170 @@
+<template>
+  <AnchoredSection id="contact">
+    <LayoutContainer>
+      <!-- Section "Appelez nous" -->
+      <v-row class="center-90">
+        <LayoutUISubTitle v-if="smAndDown"> Contactez-nous </LayoutUISubTitle>
+
+        <v-col cols="12" md="6">
+          <v-img
+            src="/images/components/contact/Contact_Opentalent_agenda_et_logiciels_culturels.jpg"
+            alt="Téléphone fixe posé sur un fond bleu comportant des bulles d’onomatopée : HAHA! OH! HEY! WOW! "
+            :cover="mdAndDown"
+            class="help-img"
+          />
+        </v-col>
+
+        <v-col cols="12" lg="5" class="contact-section">
+          <LayoutUISubTitle v-if="mdAndUp"> Contactez-nous </LayoutUISubTitle>
+
+          <LayoutUITitle> Vous avez un projet ? </LayoutUITitle>
+
+          <div class="px-6">
+            <p class="contact-details">
+              Vous avez une identité, des besoins, des projets... On est là pour
+              vous écouter et vous offrir une offre personnalisée ! Que vous
+              soyez une petite ou une structure plus conséquente, notre offre
+              s'adapte à toutes les tailles : le prix de l’abonnement au
+              logiciel varie en fonction du nombre d'élèves, tout en conservant
+              l'intégralité des fonctionnalités.
+            </p>
+
+            <v-btn to="nous-contacter" class="btn-contact">
+              Nous contacter
+            </v-btn>
+          </div>
+        </v-col>
+      </v-row>
+
+      <!-- Section "Adhérent CMF" -->
+      <v-row class="center-90 cmf-section">
+        <v-col cols="12" lg="6">
+          <LayoutUISubTitle> Adhérents CMF </LayoutUISubTitle>
+
+          <LayoutUITitle> Bénéficiez de conditions privilégiées </LayoutUITitle>
+
+          <div class="pl-4">
+            <v-img v-if="mdAndDown"
+              src="/images/logos/cmf/Logo_Confederation_Musicale_de_France-CMF_vivre_la_musique_ensemble.jpg"
+              alt="Logo Confédération Musicale de France - CMF avec son slogan : vivre la musique ensemble"
+              class="logo-cmf my-6"
+            />
+
+            <p class="contact-details">
+              Si votre établissement d’enseignement artistique est adhérent à la
+              Confédération Musicale de France (CMF), vous bénéficiez
+              gratuitement, dans le cadre de votre adhésion, de la version
+              Opentalent Artist standard et de conditions privilégiées pour la
+              version Opentalent School. <br />
+            </p>
+
+            <p class="mt-6 contact-details">
+              Contactez-nous directement ou contactez votre fédération pour
+              obtenir vos codes d’accès.
+            </p>
+
+            <v-btn
+              href="https://www.cmf-musique.org/contact/"
+              target="_blank"
+              class="btn-contact"
+            >
+              Obtenir mon code d'accès
+            </v-btn>
+          </div>
+        </v-col>
+
+        <v-col v-if="mdAndUp" cols="12" md="6">
+          <v-img
+            src="/images/logos/cmf/Logo_Confederation_Musicale_de_France-CMF_vivre_la_musique_ensemble.jpg"
+            alt="Logo Confédération Musicale de France - CMF avec son slogan : vivre la musique ensemble"
+            class="logo-cmf mt-12"
+          />
+        </v-col>
+      </v-row>
+    </LayoutContainer>
+  </AnchoredSection>
+</template>
+<script setup>
+import { useDisplay } from 'vuetify'
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+
+const { smAndDown, mdAndDown, mdAndUp } = useDisplay()
+</script>
+
+<style scoped>
+.help-img {
+  width: 100%;
+  height: 90%;
+  object-fit: cover;
+  object-position: center;
+}
+
+.logo-cmf {
+  background-repeat: no-repeat;
+  background-size: contain;
+  width: 50%;
+  min-width: 250px;
+  height: 100%;
+  margin-left: 100px;
+
+  @media (max-width: 1240px) {
+    margin: 12px auto 48px auto !important;
+  }
+}
+
+.btn-contact {
+  margin-top: 1rem;
+  height: 53px;
+  background: var(--secondary-color);
+  border-radius: 6px;
+  color: var(--on-secondary-color);
+  padding: 19px 28px;
+  gap: 9px;
+  max-width: 90%;
+}
+
+.subtitle {
+  font-weight: 400;
+  font-size: 34px;
+  line-height: 38px;
+  color: var(--on-neutral-color);
+  margin-bottom: 2rem;
+}
+
+.contact-details {
+  font-weight: 300;
+  font-size: 16px;
+  line-height: 20px;
+  color: var(--on-neutral-color);
+  max-width: 80%;
+
+}
+
+@media (max-width: 1240px) {
+  .contact-section {
+    text-align: center;
+  }
+
+  .cmf-section {
+    text-align: center;
+  }
+
+  .contact-details {
+    margin: 0 auto;
+  }
+}
+
+@media (max-width: 1600px) and (min-width: 600px) {
+  .contact-details {
+    width: 30rem !important;
+  }
+}
+
+@media (max-width: 600px) {
+  .contact-details {
+    max-width: 100%;
+    width: 100%;
+    text-align: justify;
+  }
+}
+</style>

+ 26 - 7
components/Common/ContainerVideo.vue

@@ -1,6 +1,6 @@
 <template>
   <LayoutContainer>
-    <div class="container-green">
+    <div v-if="videoUrl" class="container-green">
       <v-row class="mt-12">
         <v-row>
           <v-col cols="6">
@@ -8,7 +8,7 @@
               {{ title }}
             </LayoutUISubTitle>
 
-            <p class="quote">
+            <p v-if="lgAndUp" class="quote">
               {{ quote }}
             </p>
           </v-col>
@@ -23,19 +23,29 @@
         </v-row>
       </v-row>
     </div>
+
+    <div v-else></div>
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-const props = defineProps({
+import { useDisplay } from 'vuetify'
+
+const { lgAndUp } = useDisplay()
+
+defineProps({
   title: {
     type: String,
-    required: true
+    required: true,
   },
   quote: {
     type: String,
-    required: true
-  }
+    required: true,
+  },
+  videoUrl: {
+    type: String,
+    default: '',
+  },
 })
 </script>
 
@@ -61,11 +71,16 @@ const props = defineProps({
 }
 
 .screen-img-3 {
-  background-image: url("/images/logiciels/school/screen2.png");
+  background-image: url('/images/components/presentation/Opentalent-disponible-su-Multi-support.png');
   background-size: cover;
   background-position: center;
   width: 650px;
   height: 650px;
+
+  @media (max-width: 1240px) {
+    width: 400px;
+    height: 400px;
+  }
 }
 
 .quote {
@@ -87,5 +102,9 @@ const props = defineProps({
   background: linear-gradient(180deg, rgba(14, 45, 50, 0) 26.84%, #0e2d32 100%),
     rgba(7, 27, 31, 0.3);
   height: 40rem;
+
+  @media (max-width: 1240px) {
+    height: 400px;
+  }
 }
 </style>

+ 20 - 22
components/Common/MenuScroll.vue

@@ -4,9 +4,7 @@ Menu de navigation entre les sections d'une page, accrochée au haut de l'écran
 <template>
   <LayoutContainer v-scroll="handleScroll">
     <v-row>
-      <v-col
-        cols="12"
-      >
+      <v-col cols="12">
         <v-list
           class="menu-container"
           density="compact"
@@ -23,7 +21,7 @@ Menu de navigation entre les sections d'une page, accrochée au haut de l'écran
           <div v-for="menu in menus" :key="menu.anchor">
             <nuxt-link :to="{ path: '', hash: '#' + menu.anchor }">
               <v-list-item
-                :class="{ active : isSticky && menu.anchor === activeMenuItem }"
+                :class="{ active: isSticky && menu.anchor === activeMenuItem }"
               >
                 {{ menu.label }}
               </v-list-item>
@@ -36,38 +34,38 @@ Menu de navigation entre les sections d'une page, accrochée au haut de l'écran
 </template>
 
 <script setup lang="ts">
-import type { PropType } from "@vue/runtime-core";
-import type { MenuScroll } from "~/types/interface";
-import { useLayoutStore } from "~/stores/layoutStore";
+import type { ComputedRef, PropType, Ref } from 'vue'
+import type { MenuScroll } from '~/types/interface'
+import { useLayoutStore } from '~/stores/layoutStore'
 
 defineProps({
   menus: {
-    type: Array as PropType<Array < MenuScroll >>,
-    required: true
-  }
-});
+    type: Array as PropType<Array<MenuScroll>>,
+    required: true,
+  },
+})
 
 const layoutStore = useLayoutStore()
 
-const isSticky: Ref<boolean> = ref(false);
+const isSticky: Ref<boolean> = ref(false)
 
 const activeMenuItem: ComputedRef<string | null> = computed(() => {
-  return Object.entries(
-    layoutStore.isAnchoredSectionOnScreen
-  ).find(
-    ([key, value]) => value === true
-  )?.[0] ?? null
+  return (
+    Object.entries(layoutStore.isAnchoredSectionOnScreen).find(
+      ([_, value]) => value
+    )?.[0] ?? null
+  )
 })
 
 const handleScroll = () => {
-  isSticky.value = window.scrollY > 800;
+  isSticky.value = window.scrollY > 800
 }
 </script>
 
 <style scoped lang="scss">
 .sticky-menu {
   position: fixed;
-  top: 0;
+  top: 0 !important;
   left: 0;
   right: 0;
   background: var(--neutral-color);
@@ -75,6 +73,7 @@ const handleScroll = () => {
 }
 
 .menu-container {
+  top: -32px;
   z-index: 3;
   display: flex;
   justify-content: center;
@@ -99,10 +98,9 @@ const handleScroll = () => {
 }
 
 .active {
-  background-color: var(--on-primary-color);
-  color: var(--primary-color);
+  background-color: var(--scroll-menu-primary-color);
+  color: var(--scroll-menu-on-primary-color);
   border-radius: 16px;
   padding: 5px;
 }
 </style>
-

+ 31 - 29
components/Common/Meta.vue

@@ -1,36 +1,38 @@
 <!--
 Définit les balises meta de la page
 -->
-<template></template>
+<template>
+  <div />
+</template>
 
 <script setup lang="ts">
-  const props = defineProps({
-    title: {
-      type: String,
-      required: true
-    },
-    description: {
-      type: String,
-      required: true
-    },
-    image: {
-      type: String,
-      required: false,
-      default: 'images/Opentalent'
-    }
-  })
+const props = defineProps({
+  title: {
+    type: String,
+    required: true,
+  },
+  description: {
+    type: String,
+    required: true,
+  },
+  image: {
+    type: String,
+    required: false,
+    default: 'images/Opentalent',
+  },
+})
 
-  useSeoMeta({
-    title : props.title,
-    ogTitle : props.title,
-    twitterTitle : props.title,
-    description : props.description,
-    ogDescription : props.description,
-    twitterDescription : props.description,
-    ogImage : props.image,
-    twitterImage: props.image,
-    twitterCard : 'summary_large_image',
-    ogType: 'website',
-    ogLocale: 'fr_FR'
-  })
+useSeoMeta({
+  title: props.title,
+  ogTitle: props.title,
+  twitterTitle: props.title,
+  description: props.description,
+  ogDescription: props.description,
+  twitterDescription: props.description,
+  ogImage: props.image,
+  twitterImage: props.image,
+  twitterCard: 'summary_large_image',
+  ogType: 'website',
+  ogLocale: 'fr_FR',
+})
 </script>

+ 125 - 99
components/Common/Presentation.vue

@@ -2,146 +2,137 @@
 Section "Présentation" d'une page Logiciel
 -->
 <template>
-  <div id="Presentation">
-    <LayoutContainer>
-      <v-row class="center-90">
-
-        <!-- Colonne 1 (sous-titre, illustration logiciels, prix) -->
-        <v-col cols="5">
-          <LayoutUISubTitle class="ml-8" >
-            {{ title }}
-          </LayoutUISubTitle>
-
-          <v-img
-            src="/images/logiciels/Opentalent-disponible-su-Multi-support.png"
-            class="w-100"
-          />
-
-          <div class="pricing-rectangle rectangle-4 ml-6">
-            <div class="logo-circle">
-              <div class="content-flex ml-6">
-                <v-img
-                  :src="logoSrc"
-                  class="software-logo"
-                />
-              </div>
-            </div>
+  <LayoutContainer>
+    <v-row class="center-90">
+      <!-- Colonne 1 (sous-titre, illustration logiciels, prix) -->
+      <v-col cols="12" lg="5">
+        <LayoutUISubTitle class="ml-8">
+          {{ title }}
+        </LayoutUISubTitle>
 
-            <div v-if="pricingAmount" class="details">
-              <p class="small-text">
-                {{ pricingFromText }}
-              </p>
-              <p class="big-text">
-                {{ pricingAmount }}
-                <span class="smaller-text">
-                  {{ pricingPeriodText }}
-                </span>
-              </p>
-              <p class="small-text">
-                {{ pricingAnnouncementText }}
-              </p>
-            </div>
-            <div v-else class="details medium-text">
-              {{ pricingAltText }}
+        <v-img
+          src="/images/components/presentation/Opentalent-disponible-su-Multi-support.png"
+          alt="Ordinateur de bureau, ordinateur portable tablette et smartphone montrant le logiciel Opentalent"
+          class="w-100"
+        />
+
+        <div class="pricing-rectangle rectangle-4 ml-6">
+          <div class="logo-circle">
+            <div class="content-flex ml-6">
+              <v-img :src="logoSrc" :alt="logoAlt" class="software-logo" />
             </div>
           </div>
-        </v-col>
-
-        <!-- Colonne 2 (présentation, pictogrammes des fonctionnalités) -->
-        <v-col cols="6">
-          <h3>
-            {{ section1title }}
-          </h3>
-
-          <ul class="ml-12 mt-6">
-            <li
-              v-for="item in features"
-              :key="item"
-            >
-              {{ item }}
-            </li>
-          </ul>
-
-          <h3 class="mt-12 ml-6">
-            {{ section2title }}
-          </h3>
-
-          <div class="d-flex flex-row">
-            <div
-              v-for="picto in pictos"
-              :key="picto.text"
-              class="picto"
-            >
-              <v-img :src="picto.src" class="img" />
-
-              <p class="text">
-                {{ picto.text }}
-              </p>
-            </div>
+
+          <div v-if="pricingAmount" class="details">
+            <p class="small-text">
+              {{ pricingFromText }}
+            </p>
+            <p class="big-text">
+              {{ pricingAmount }}
+              <span class="smaller-text">
+                {{ pricingPeriodText }}
+              </span>
+            </p>
+            <p class="small-text">
+              {{ pricingAnnouncementText }}
+            </p>
+          </div>
+          <div v-else class="details medium-text">
+            {{ pricingAltText }}
+          </div>
+        </div>
+      </v-col>
+
+      <!-- Colonne 2 (présentation, pictogrammes des fonctionnalités) -->
+      <v-col cols="12" lg="6">
+        <h3>
+          {{ section1title }}
+        </h3>
+
+        <ul class="ml-12 mt-6">
+          <li v-for="item in features" :key="item">
+            {{ item }}
+          </li>
+        </ul>
+
+        <h3 class="mt-12 ml-6">
+          {{ section2title }}
+        </h3>
+
+        <div class="picto-container">
+          <div v-for="picto in pictos" :key="picto.text" class="picto">
+            <v-img :src="picto.src" class="img" />
+
+            <p class="text">
+              {{ picto.text }}
+            </p>
           </div>
-        </v-col>
-      </v-row>
-    </LayoutContainer>
-  </div>
+        </div>
+      </v-col>
+    </v-row>
+  </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-import type { PropType } from "@vue/runtime-core";
-import type { FeaturePicto } from "~/types/interface";
+import type { PropType } from 'vue'
+import type { FeaturePicto } from '~/types/interface'
 
-const route = useRoute();
-
-const props = defineProps({
+defineProps({
   title: {
     type: String,
-    required: true
+    required: true,
   },
   section1title: {
     type: String,
     required: false,
-    default: "Un outil complet en ligne"
+    default: 'Un outil complet en ligne',
   },
   section2title: {
     type: String,
     required: false,
-    default: "Des caractéristiques uniques & dédiée"
+    default: 'Des caractéristiques uniques & dédiée',
   },
   features: {
     type: Object as PropType<Array<string>>,
-    required: true
+    required: true,
   },
   pictos: {
     type: Array as PropType<Array<FeaturePicto>>,
-    required: true
+    required: true,
   },
   logoSrc: {
     type: String,
-    default: "",
+    default: '',
+  },
+  logoAlt: {
+    type: String,
+    default: '',
   },
   pricingFromText: {
     type: String,
     required: false,
-    default: "à partir de"
+    default: 'à partir de',
   },
   pricingAmount: {
     type: String,
-    default: ""
+    default: '',
   },
   pricingPeriodText: {
     type: String,
     required: false,
-    default: "mois"
+    default: '/ mois',
   },
   pricingAnnouncementText: {
     type: String,
     required: false,
-    default: "payable annuellement"
+    default: 'payable annuellement',
   },
   pricingAltText: {
+    type: String,
     required: false,
-    default: ""
-  }
-});
+    default: '',
+  },
+})
 </script>
 
 <style scoped lang="scss">
@@ -157,7 +148,7 @@ const props = defineProps({
   .logo-circle {
     background-color: #0e2d32;
     border-radius: 3rem;
-    width: 7rem;
+    width: 6rem;
     height: 6rem;
   }
 
@@ -165,8 +156,8 @@ const props = defineProps({
     display: flex;
     align-items: center;
     justify-content: center;
-    top:1rem;
-    right: .5rem;
+    top: 1.3rem;
+    right: 0.7rem;
   }
 
   .details {
@@ -190,7 +181,7 @@ const props = defineProps({
     font-size: 2.5rem;
     font-weight: bold;
     line-height: 2rem;
-    margin-left: 1rem;
+    margin-left: 0.8rem;
   }
 
   .smaller-text {
@@ -201,6 +192,25 @@ const props = defineProps({
     font-size: 1.5rem;
     font-weight: 400;
   }
+
+  @media (max-width: 600px) {
+    width: 280px;
+
+    .details {
+      margin-left: 0;
+    }
+  }
+}
+
+.picto-container {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+
+  @media (max-width: 1240px) {
+    flex-wrap: wrap;
+    justify-content: center;
+  }
 }
 
 .picto {
@@ -215,6 +225,7 @@ const props = defineProps({
     margin-top: -3rem;
     text-align: center;
     width: 60%;
+    height: 100px;
     margin-right: auto;
     margin-left: auto;
   }
@@ -226,6 +237,20 @@ const props = defineProps({
     background-repeat: no-repeat;
     background-position: center;
   }
+
+  @media (max-width: 600px) {
+    width: 50%;
+    margin: 0 auto;
+
+    .text {
+      width: 90%;
+    }
+
+    .img {
+      width: 100%;
+      height: 100%;
+    }
+  }
 }
 
 h3 {
@@ -233,6 +258,7 @@ h3 {
   font-size: 34px;
   font-weight: 400;
   line-height: 38px;
+  max-width: 90%;
 }
 
 h3:first-child {

+ 111 - 85
components/Common/ReviewSection.vue

@@ -1,93 +1,86 @@
 <template>
-    <LayoutContainer>
-      <v-row class="center-90">
-        <v-col cols="3">
-          <div class="controls-section">
-            <h3>
-              Ce sont eux qui en parlent le mieux
-            </h3>
-
-            <div class="carousel-controls">
-              <v-btn
-                icon="fas fa-chevron-left"
-                @click="goPrevious"
-              />
-              <v-btn
-                icon="fas fa-chevron-right"
-                @click="goNext"
-              />
-            </div>
+  <LayoutContainer>
+    <v-row class="center-90">
+      <v-col cols="12" lg="3">
+        <div class="controls-section">
+          <h3>Ce sont eux qui en parlent le mieux</h3>
+
+          <div class="carousel-controls">
+            <v-btn icon="fas fa-chevron-left" @click="goPrevious" />
+            <v-btn icon="fas fa-chevron-right" @click="goNext" />
           </div>
-        </v-col>
-
-        <v-col cols="9">
-          <Carousel
-            ref="carousel"
-            :items-to-show="3"
-            :items-to-scroll="1"
-            :wrap-around="true"
-          >
-            <Slide
-              v-for="(card, index) in cards"
-              :key="index"
-              class="card"
-            >
-              <v-container>
-                <v-card class="inv-theme">
-                  <v-card-item>
-                    <v-card-text>
-                      {{ card.review }}
-                    </v-card-text>
-                  </v-card-item>
-
-                  <v-card-actions>
-                    <p class="reviewer-name">
-                      {{ card.name }}
-                    </p>
-
-                    <p class="reviewer-status">
-                      {{ card.status }}
-                    </p>
-                    <p class="reviewer-structure">
-                      {{ card.structure }}
-                    </p>
-                  </v-card-actions>
-                </v-card>
-              </v-container>
-            </Slide>
-          </Carousel>
-        </v-col>
-      </v-row>
+        </div>
+      </v-col>
+
+      <v-col cols="12" lg="9">
+        <Carousel
+          ref="carousel"
+          :items-to-show="lgAndUp ? 3 : 1"
+          :wrap-around="true"
+          :show-arrows="false"
+          snap-align="center"
+          class="carousel"
+        >
+          <Slide v-for="(card, index) in cards" :key="index" class="card">
+            <v-container>
+              <v-card class="inv-theme">
+                <v-card-item>
+                  <v-card-text>
+                    <i>"{{ card.review }}"</i>
+                  </v-card-text>
+                </v-card-item>
+
+                <v-card-actions>
+                  <p class="reviewer-name">
+                    {{ card.name }}
+                  </p>
+
+                  <p class="reviewer-status">
+                    {{ card.status }}
+                  </p>
+                  <p class="reviewer-structure">
+                    {{ card.structure }}
+                  </p>
+                </v-card-actions>
+              </v-card>
+            </v-container>
+          </Slide>
+        </Carousel>
+      </v-col>
+    </v-row>
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-import { Carousel, Slide } from "vue3-carousel";
-import "vue3-carousel/dist/carousel.css";
-import type { PropType } from "@vue/runtime-core";
-import type { Review } from "~/types/interface";
+import { Carousel, Slide } from 'vue3-carousel'
+import 'vue3-carousel/dist/carousel.css'
+import type { PropType, Ref } from 'vue'
+import { useDisplay } from 'vuetify'
+import type { Review } from '~/types/interface'
 
-const props = defineProps({
+defineProps({
   cards: {
     type: Array as PropType<Array<Review>>,
     required: true,
   },
-});
+})
 
-const carousel: Ref<typeof Carousel | null> = ref(null);
+const { lgAndUp } = useDisplay()
+
+const carousel: Ref<typeof Carousel | null> = ref(null)
 
 const goPrevious = () => {
-  carousel.value!.prev();
-};
+  carousel.value!.prev()
+}
 
 const goNext = () => {
-  carousel.value!.next();
-};
+  carousel.value!.next()
+}
 </script>
 
 <style scoped lang="scss">
 .v-container {
-  padding: 0 !important;
+  padding: 0 0 48px 0 !important;
 }
 
 .controls-section {
@@ -125,30 +118,54 @@ const goNext = () => {
     margin-right: 1rem;
     margin-bottom: 2rem;
     border-radius: 0;
+
+    @media (max-width: 1240px) {
+      margin-top: 2rem;
+      margin-bottom: 1rem;
+    }
   }
 }
 
 .carousel {
+  @media (max-width: 1240px) {
+    left: -36px;
+  }
+
+  .v-container {
+    height: 100%;
+  }
+
   .v-card {
     display: flex;
     flex-direction: column;
     padding: 0 0.5rem;
     border-radius: 1rem;
-    min-height: 300px;
-    max-height: 300px;
     margin-top: 2rem;
     margin-bottom: 0.6rem;
+    height: 100%;
+
+    @media (max-width: 1240px) {
+      max-width: 70%;
+      margin: 0 auto 48px auto;
+    }
+
+    @media (max-width: 600px) {
+      height: auto;
+    }
   }
 
   .v-card-item {
-    flex: 1
+    flex: 1;
+
+    @media (max-width: 600px) {
+      flex: 0;
+    }
   }
 
   .v-card-text {
-    text-align: justify;
     min-height: 120px;
     overflow: auto;
-    font-size: 0.9rem;
+    font-size: 1rem;
     flex: 1;
   }
 
@@ -175,7 +192,15 @@ const goNext = () => {
     align-items: center;
     letter-spacing: 0.18em;
     text-transform: uppercase;
-    text-align: justify !important;
+
+    @media (min-width: 600px) {
+      text-align: justify !important;
+    }
+
+    @media (max-width: 600px) {
+      margin: 12px auto;
+      text-align: center !important;
+    }
   }
 
   .reviewer-structure {
@@ -187,11 +212,7 @@ const goNext = () => {
     margin-bottom: 1rem;
   }
 
-  @media (min-width:2100px) {
-    .v-card-text {
-      min-height: 150px !important;
-      max-height: 150px !important;
-    }
+  @media (max-width: 1240px) {
   }
 }
 
@@ -200,10 +221,15 @@ const goNext = () => {
   border-radius: 1rem;
 }
 
-@media (min-width:2100px) {
-  .v-card {
-    min-height: 360px !important;
-    max-height: 360px !important;
+.v-card-item {
+  display: block;
+  padding-top: 16px;
+}
+
+@media (max-width: 600px) {
+  :deep(.v-carousel__controls) {
+    color: var(--on-neutral-color);
+    background-color: var(--neutral-color);
   }
 }
 </style>

+ 47 - 47
components/Common/Share.vue

@@ -7,60 +7,60 @@
       target="_blank"
       :style="{ color: network.colorOnHover }"
     >
-      <v-icon :icon="network.icon"/>
+      <v-icon :icon="network.icon" />
     </nuxt-link>
   </div>
 </template>
 
 <script setup lang="ts">
-  import type { SocialNetworkShareBtn } from "~/types/interface";
+import type { Ref } from 'vue'
+import type { SocialNetworkShareBtn } from '~/types/interface'
 
-  const url: Ref<string | null> = ref(null)
-  const networks: Ref<Array<SocialNetworkShareBtn>> = ref([])
+const url: Ref<string | null> = ref(null)
+const networks: Ref<Array<SocialNetworkShareBtn>> = ref([])
 
-  if (process.client) {
-    url.value = window.location.href
-
-    networks.value = [
-      {
-        name: "Facebook",
-        icon: "fa-brands fa-facebook",
-        colorOnHover: "#135fc2",
-        url: `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url.value)}`
-      },
-      {
-        name: "Twitter",
-        icon: "fa-brands fa-twitter",
-        colorOnHover: "#1781c2",
-        url: `https://twitter.com/intent/tweet?url=${encodeURIComponent(url.value)}`
-      },
-      {
-        name: "Messenger",
-        icon: "fa-brands fa-facebook-messenger",
-        colorOnHover: "#0085ff",
-        url: `https://messenger.com`
-      },
-      {
-        name: "Instagram",
-        icon: "fa-brands fa-instagram",
-        colorOnHover: "#d0006a",
-        url: "https://instagram.com"
-      },
-      {
-        name: "Linkedin",
-        icon: "fa-brands fa-linkedin",
-        colorOnHover: "#006291",
-        url: `https://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent(url.value)}`
-      },
-      {
-        name: "Email",
-        icon: "fas fa-envelope",
-        colorOnHover: "#292929",
-        url: `mailto:?body=${url.value}`
-      },
-    ]
-  }
+if (process.client) {
+  url.value = window.location.href
 
+  networks.value = [
+    {
+      name: 'Facebook',
+      icon: 'fa-brands fa-facebook',
+      colorOnHover: '#135fc2',
+      url: `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url.value)}`,
+    },
+    {
+      name: 'Twitter',
+      icon: 'fa-brands fa-twitter',
+      colorOnHover: '#1781c2',
+      url: `https://twitter.com/intent/tweet?url=${encodeURIComponent(url.value)}`,
+    },
+    {
+      name: 'Messenger',
+      icon: 'fa-brands fa-facebook-messenger',
+      colorOnHover: '#0085ff',
+      url: `https://messenger.com`,
+    },
+    {
+      name: 'Instagram',
+      icon: 'fa-brands fa-instagram',
+      colorOnHover: '#d0006a',
+      url: 'https://instagram.com',
+    },
+    {
+      name: 'Linkedin',
+      icon: 'fa-brands fa-linkedin',
+      colorOnHover: '#006291',
+      url: `https://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent(url.value)}`,
+    },
+    {
+      name: 'Email',
+      icon: 'fas fa-envelope',
+      colorOnHover: '#292929',
+      url: `mailto:?body=${url.value}`,
+    },
+  ]
+}
 </script>
 
 <style scoped lang="scss">
@@ -74,7 +74,7 @@
   i {
     font-size: 32px;
     margin: 0.5rem 0.3rem;
-    color: var(--on-neutral-color-light);
+    color: var(--primary-color);
   }
 
   a:hover i {

+ 169 - 12
components/Common/Table/Comparatif.vue

@@ -1,10 +1,10 @@
 <template>
   <LayoutContainer>
     <v-row class="center-90">
-      <table>
+      <table v-if="mdAndUp">
         <thead>
           <tr>
-            <th/>
+            <th />
 
             <th>
               <p class="standard">Standard</p>
@@ -27,10 +27,7 @@
         </thead>
 
         <tbody>
-          <tr
-            v-for="(item, index) in items"
-            :key="item.label"
-          >
+          <tr v-for="item in items" :key="item.label">
             <td class="label-column">
               {{ item.label }}
             </td>
@@ -75,28 +72,147 @@
           </tr>
         </tbody>
       </table>
+
+      <div v-else>
+        <div class="d-flex flex-row flex-grow-1 justify-center mt-2">
+          <v-btn
+            :disabled="carouselPos === 0"
+            icon="fas fa-chevron-left"
+            class="mr-6"
+            @click="goToPrevious"
+          />
+          <v-btn
+            :disabled="carouselPos === 1"
+            icon="fas fa-chevron-right"
+            @click="goToNext"
+          />
+        </div>
+
+        <v-carousel
+          v-model="carouselPos"
+          :hide-delimiters="true"
+          :show-arrows="false"
+          :height="height"
+        >
+          <v-carousel-item>
+            <h4>Standard</h4>
+            <div>
+              <p class="from">À partir de</p>
+              <p class="price">
+                {{ standardPrice }} <span class="ttc">ttc</span>
+                <span class="month">/mois</span>
+              </p>
+            </div>
+
+            <table>
+              <tbody>
+                <tr v-for="item in items" :key="item.label">
+                  <td class="label-column">
+                    {{ item.label }}
+                  </td>
+
+                  <td>
+                    <v-icon
+                      v-if="item.includedInStandard === true"
+                      icon="far fa-check-circle"
+                      size="18"
+                    />
+
+                    <v-icon
+                      v-else-if="item.includedInStandard === false"
+                      icon="far fa-times-circle"
+                      size="18"
+                      color="red"
+                    />
+
+                    <span v-else>
+                      {{ item.includedInStandard }}
+                    </span>
+                  </td>
+                </tr>
+              </tbody>
+            </table>
+          </v-carousel-item>
+
+          <v-carousel-item>
+            <h4>Premium</h4>
+
+            <div>
+              <p class="from">À partir de</p>
+              <p class="price">
+                {{ premiumPrice }} <span class="ttc">ttc</span>
+                <span class="month">/mois</span>
+              </p>
+            </div>
+
+            <table>
+              <tbody>
+                <tr v-for="item in items" :key="item.label">
+                  <td class="label-column">
+                    {{ item.label }}
+                  </td>
+
+                  <td>
+                    <v-icon
+                      v-if="item.includedInPremium === true"
+                      icon="far fa-check-circle"
+                      size="18"
+                    />
+
+                    <v-icon
+                      v-else-if="item.includedInPremium === false"
+                      icon="far fa-times-circle"
+                      size="18"
+                      color="red"
+                    />
+
+                    <span v-else>
+                      {{ item.includedInPremium }}
+                    </span>
+                  </td>
+                </tr>
+              </tbody>
+            </table>
+          </v-carousel-item>
+        </v-carousel>
+      </div>
     </v-row>
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
+import { useDisplay } from 'vuetify'
+import type { PropType } from 'vue'
+import type { ComparisonItem } from '~/types/interface'
 
-import type { ComparisonItem } from "~/types/interface";
+const { mdAndUp } = useDisplay()
 
 const props = defineProps({
   standardPrice: {
     type: String,
-    required: true
+    required: true,
   },
   premiumPrice: {
     type: String,
-    required: true
+    required: true,
   },
   items: {
     type: Array as PropType<Array<ComparisonItem>>,
-    required: true
-  }
-});
+    required: true,
+  },
+})
+
+const height = computed(() => 150 + props.items.length * 48)
+
+const carouselPos = ref(0)
+
+const goToPrevious = () => {
+  carouselPos.value = 0
+}
+
+const goToNext = () => {
+  carouselPos.value = 1
+}
 </script>
 
 <style scoped lang="scss">
@@ -114,6 +230,10 @@ table {
   margin-left: auto;
   border: none;
   border-collapse: collapse;
+
+  @media (max-width: 940px) {
+    width: 100%;
+  }
 }
 
 th {
@@ -121,6 +241,10 @@ th {
   font-weight: 400;
   font-size: 30px;
   line-height: 34px;
+
+  @media (max-width: 600px) {
+    font-size: 18px;
+  }
 }
 
 tr {
@@ -134,6 +258,10 @@ tbody tr:nth-child(even) {
 
 td {
   padding-right: 5rem;
+
+  @media (max-width: 600px) {
+    padding-right: 0;
+  }
 }
 
 td:first-child {
@@ -145,6 +273,10 @@ td:first-child {
   letter-spacing: 0.18em;
   text-transform: uppercase;
   color: var(--on-neutral-color-alt);
+
+  @media (max-width: 600px) {
+    padding-left: 5px;
+  }
 }
 
 .standard {
@@ -183,5 +315,30 @@ td:first-child {
 
 .month {
   padding-right: 5rem;
+
+  @media (max-width: 600px) {
+    padding-right: 0;
+  }
+}
+
+.v-carousel {
+  h4 {
+    text-align: center;
+    margin: 24px auto 12px auto;
+    text-transform: uppercase;
+    letter-spacing: 0.25em;
+  }
+
+  p {
+    padding-right: 0;
+  }
+
+  .price {
+    margin-top: 12px;
+  }
+
+  .ttc {
+    padding-right: 10px;
+  }
 }
 </style>

+ 36 - 46
components/Contact/AddressSection.vue

@@ -5,27 +5,18 @@
         <ContactMap class="contact-map" />
       </v-col>
       <v-col cols="6" class="address-col px-8">
-
-        <h4>
-          <v-icon icon="fas fa-envelope"/> Pour nous écrire
-        </h4>
+        <h4><v-icon icon="fas fa-envelope" /> Pour nous écrire</h4>
 
         <v-card>
-          <div>
-            2iOpenService
-          </div>
-          <div>
-            217, rue Raoul Follereau
-          </div>
-          <div>
-            74300 - Cluses
-          </div>
+          <div>2iOpenService</div>
+          <div>217, rue Raoul Follereau</div>
+          <div>74300 - Cluses</div>
         </v-card>
 
         <div class="mb-6" />
 
         <h4>
-          <v-icon icon="fas fa-phone"/>
+          <v-icon icon="fas fa-phone" />
           Ou par téléphone
         </h4>
 
@@ -39,9 +30,7 @@
           <span v-else>
             <v-card>
               Contactez nous au
-              <a href="tel:+33972126017">
-                09 72 12 60 17
-              </a>
+              <a href="tel:+33972126017"> 09 72 12 60 17 </a>
             </v-card>
           </span>
         </div>
@@ -51,42 +40,43 @@
 </template>
 
 <script setup lang="ts">
-  const revealPhoneNumber = ref(false)
+const revealPhoneNumber = ref(false)
 </script>
 
 <style scoped lang="scss">
-  .container {
-    width: 70%;
-  }
+.container {
+  width: 70%;
+}
 
-  h4 {
-    display: flex;
-    flex-direction: row;
-    color: var(--primary-color);
-    font-size: 20px;
-    font-weight: 500;
-    margin: 24px 0;
-  }
+h4 {
+  display: flex;
+  flex-direction: row;
+  color: var(--primary-color);
+  font-size: 20px;
+  font-weight: 500;
+  margin: 24px 0;
+}
 
-  .v-icon {
-    margin-right: 16px;
-  }
+.v-icon {
+  margin-right: 16px;
+}
 
-  .address-col > div, .address-col > .v-card > div {
-    padding: 8px 16px;
-  }
+.address-col > div,
+.address-col > .v-card > div {
+  padding: 8px 16px;
+}
 
-  .v-card {
-    margin: 16px 64px;
-    padding: 12px;
-  }
+.v-card {
+  margin: 16px 64px;
+  padding: 12px;
+}
 
-  .v-btn {
-    margin: 16px 64px;
-  }
+.v-btn {
+  margin: 16px 64px;
+}
 
-  a {
-    color: var(--on-neutral-color);
-    text-decoration: underline;
-  }
+a {
+  color: var(--on-neutral-color);
+  text-decoration: underline;
+}
 </style>

+ 0 - 29
components/Contact/Banner.vue

@@ -1,29 +0,0 @@
-<template>
-  <LayoutContainer>
-    <LayoutUITitlePage>
-      Besoin d'aide ?
-      <template #subtitle>Notre équipe est là pour vous. Contactez-nous! </template>
-    </LayoutUITitlePage>
-
-    <v-row>
-      <v-col cols="12" class="position-relative">
-        <v-img
-          src="/images/formation/banner.jpg"
-          alt="banner"
-          cover
-          class="banner"
-        />
-      </v-col>
-    </v-row>
-  </LayoutContainer>
-</template>
-
-<style scoped lang="scss">
-.banner {
-  width: 100%;
-  height: 15rem;
-  object-position: center 30%;
-  margin: 0 auto;
-  transform: scaleX(-1);
-}
-</style>

+ 130 - 91
components/Contact/Form.vue

@@ -2,6 +2,8 @@
   <LayoutContainer>
     <div id="anchor" />
 
+    <h4><span class="line" /> Veuillez remplir le formulaire ci-dessous</h4>
+
     <v-form
       v-if="!contactRequestSent"
       ref="form"
@@ -9,25 +11,17 @@
       @submit.prevent="submit"
     >
       <v-container>
-        <h4>
-          <span class="line" /> Veuillez remplir le formulaire ci-dessous
-        </h4>
-
-        <i>Les champs dont le nom est suivi d'un astérisque (*) sont obligatoires</i>
+        <i
+          >Les champs dont le nom est suivi d'un astérisque (*) sont
+          obligatoires</i
+        >
 
-        <h6>
-          Vos coordonnées
-        </h6>
+        <h6>Vos coordonnées</h6>
 
         <!-- Gender selection -->
         <v-row>
           <v-col cols="12">
-            <v-radio-group
-              v-model="contactRequest.gender"
-              row
-              mandatory
-              inline
-            >
+            <v-radio-group v-model="contactRequest.gender" row mandatory inline>
               <v-radio label="Madame" value="Madame" />
               <v-radio label="Monsieur" value="Monsieur" />
             </v-radio-group>
@@ -68,7 +62,8 @@
           <v-col cols="12" md="6">
             <v-text-field
               v-model="contactRequest.city"
-              label="Ville"
+              label="Ville*"
+              :rules="[validateCity]"
             />
           </v-col>
         </v-row>
@@ -107,9 +102,7 @@
           </v-col>
         </v-row>
 
-        <h6>
-          Votre demande concerne *
-        </h6>
+        <h6>Votre demande concerne *</h6>
 
         <!-- Request type and product concerned  -->
         <v-row>
@@ -130,13 +123,12 @@
               :items="products"
               item-value="id"
               item-title="label"
+              variant="outlined"
             />
           </v-col>
         </v-row>
 
-        <h6>
-          Votre message
-        </h6>
+        <h6>Votre message</h6>
 
         <!-- Message  -->
         <v-row class="mb-8">
@@ -148,15 +140,20 @@
               required
               maxlength="400"
             />
-            <span class="remaining-cars-notice">{{ leftCars }} caractères restants</span>
+            <span class="remaining-cars-notice"
+              >{{ leftCars }} caractères restants</span
+            >
           </v-col>
         </v-row>
 
         <!-- Policy and  checkboxes -->
         <v-checkbox
           v-model="contactRequest.privacyPolicyAccepted"
-          :rules="[(v: boolean) => v || 'Vous devez accepter la politique de confidentialité']"
-          label="J'ai pris connaissance de la politique de confidentialité et j'accepte le traitement de mes données personnelles par Opentalent."
+          :rules="[
+            (v: boolean) =>
+              v || 'Vous devez accepter la politique de confidentialité',
+          ]"
+          label="J'ai pris connaissance de la politique de confidentialité et j'accepte le traitement de mes données personnelles par Opentalent. *"
         />
 
         <v-checkbox
@@ -166,7 +163,7 @@
 
         <div class="d-flex flex-row justify-center">
           <!-- @see https://github.com/hCaptcha/vue-hcaptcha -->
-          <LayoutCaptcha/>
+          <LayoutCaptcha />
         </div>
 
         <!-- Submit Button -->
@@ -181,91 +178,113 @@
             Envoyer
           </v-btn>
         </div>
+
+        <div v-if="errorMsg" class="error">
+          {{ errorMsg }}
+        </div>
       </v-container>
 
       <div class="legal">
-        Les données recueillies par Opentalent sont utilisées pour le traitement de votre demande et pour vous informer sur nos offres.
-        Elles sont destinées aux services Opentalent et à ses sous-traitants pour l’exécution des contrats. Conformément à la loi
-        "Informatique et Libertés du 6 Janvier 1978", vous disposez d’un droit d’accès, de modifications, de rectification et de suppression
-        des données vous concernant. Pour toute demande, adressez-vous à : Opentalent, 217 rue Raoul Follereau, 74300 CLUSES,
-        opentalent.fr s’engage à la confidentialité et à la protection de vos données.
+        Les données recueillies par Opentalent sont utilisées pour le traitement
+        de votre demande et pour vous informer sur nos offres. Elles sont
+        destinées aux services Opentalent et à ses sous-traitants pour
+        l’exécution des contrats. Conformément à la loi "Informatique et
+        Libertés du 6 Janvier 1978", vous disposez d’un droit d’accès, de
+        modifications, de rectification et de suppression des données vous
+        concernant. Pour toute demande, adressez-vous à : Opentalent, 217 rue
+        Raoul Follereau, 74300 CLUSES, opentalent.fr s’engage à la
+        confidentialité et à la protection de vos données.
       </div>
     </v-form>
 
     <div v-else class="confirmation-message d-flex flex-row justify-center">
       <v-card>
-        <v-icon icon="fas fa-check mr-1"/>
-        Votre demande de contact a bien été enregistrée, nous reviendrons vers vous dès que possible.
+        <v-icon icon="fas fa-check mr-1" />
+        Votre demande de contact a bien été enregistrée, nous reviendrons vers
+        vous dès que possible.
       </v-card>
     </div>
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-import ContactRequest from "~/models/Maestro/ContactRequest";
-import { useEntityManager } from "~/composables/data/useEntityManager";
-import { useRouter } from "vue-router";
+import { useRouter } from 'vue-router'
+import type { ComputedRef, Ref } from 'vue'
+import { reactive } from 'vue'
+import ContactRequest from '~/models/Maestro/ContactRequest'
+import { useEntityManager } from '~/composables/data/useEntityManager'
 
-const route = useRoute();
+const route = useRoute()
 const router = useRouter()
 const { em } = useEntityManager()
 
-const form: Ref<any | null> = ref(null)
+const form: Ref<HTMLElement | null> = ref(null)
 
-const requestTypes: Array<{id: string, label: string}> = [
-  { id: "CONTACT_REQUEST_INFORMATION", label: "Demande d'information"},
-  { id: "CONTACT_REQUEST_ESTIMATE", label: "Demande de devis"},
-  { id: "CONTACT_REQUEST_DEMO", label: "Demande de démonstration"},
-  { id: "CONTACT_REQUEST_OPTION", label: "Demande d'option supplémentaire"},
-  { id: "CONTACT_REQUEST_OTHER", label: "Autre"}
+const requestTypes: Array<{ id: string; label: string }> = [
+  { id: 'CONTACT_REQUEST_INFORMATION', label: "Demande d'information" },
+  { id: 'CONTACT_REQUEST_ESTIMATE', label: 'Demande de devis' },
+  { id: 'CONTACT_REQUEST_DEMO', label: 'Demande de démonstration' },
+  { id: 'CONTACT_REQUEST_OPTION', label: "Demande d'option supplémentaire" },
+  { id: 'CONTACT_REQUEST_OTHER', label: 'Autre' },
 ]
 
-const products: Array<{id: string, label: string}> = [
-  { id: "PRODUCT_AGENDA", label: "Agenda culturel"},
-  { id: "PRODUCT_ARTIST", label: "Opentalent Artist"},
-  { id: "PRODUCT_SCHOOL", label: "Opentalent School"},
-  { id: "PRODUCT_MANAGER", label: "Opentalent Manager"},
-  { id: "PRODUCT_ADVERTISING", label: "Publicité"},
-  { id: "PRODUCT_OTHER", label: "Autre"}
+const products: Array<{ id: string; label: string }> = [
+  { id: 'PRODUCT_AGENDA', label: 'Agenda culturel' },
+  { id: 'PRODUCT_ARTIST', label: 'Opentalent Artist' },
+  { id: 'PRODUCT_SCHOOL', label: 'Opentalent School' },
+  { id: 'PRODUCT_MANAGER', label: 'Opentalent Manager' },
+  { id: 'PRODUCT_ADVERTISING', label: 'Publicité' },
+  { id: 'PRODUCT_OTHER', label: 'Autre' },
 ]
 
 const defaultRequestType = route.query.request ?? 'CONTACT_REQUEST_INFORMATION'
 
-//@ts-ignore
-const contactRequest: ContactRequest = reactive(em.newInstance(ContactRequest, { requestType: defaultRequestType }))
+// @ts-ignore
+const contactRequest: ContactRequest = reactive(
+  em.newInstance(ContactRequest, { requestType: defaultRequestType })
+)
 
 // --- Validation ---
 const maxMessageLength = 2000
 
-const leftCars: ComputedRef<number> = computed(() =>
-  maxMessageLength - (contactRequest.message ? contactRequest.message.length : 0)
+const leftCars: ComputedRef<number> = computed(
+  () =>
+    maxMessageLength -
+    (contactRequest.message ? contactRequest.message.length : 0)
 )
 
-const validateName = (name: string | null) => !!name || "Le nom est obligatoire";
+const validateName = (name: string | null) => !!name || 'Le nom est obligatoire'
 
-const validateSurname = (surname: string | null) => !!surname || "Le prénom est obligatoire";
+const validateSurname = (surname: string | null) =>
+  !!surname || 'Le prénom est obligatoire'
 
 const validatePostalCode = (postalCode: string | null) =>
-  (!!postalCode && /^\d{5}$/.test(postalCode)) || "Le code postal doit être valide";
+  (!!postalCode && /^\d{5}$/.test(postalCode)) ||
+  'Le code postal doit être valide'
+
+const validateCity = (city: string | null) =>
+  !!city || 'La ville est obligatoire'
 
 const validateEmail = (email: string | null) =>
-  (!!email && /.+@.+\..+/.test(email)) || "L'adresse e-mail doit être valide";
+  (!!email && /.+@.+\..+/.test(email)) || "L'adresse e-mail doit être valide"
 
-const validatePhone = (email: string | null) =>
-  (!!email && /^((\+|00)33\s?|0)[1-7]([\s.]?\d{2}){4}$/.test(email)) || "Le numéro de téléphone doit être valide";
+const validatePhone = (phone: string | null) =>
+  (!!phone && /^((\+|00)33\s?|0)[1-9]([\s.]?\d{2}){4}$/.test(phone)) ||
+  'Le numéro de téléphone doit être valide'
 
 const validateStructureName = (structureName: string | null) =>
-  !!structureName || "Le nom de la structure est requis";
+  !!structureName || 'Le nom de la structure est requis'
 
 const validateNonEmptyMessage = (message: string | null) =>
-  (!!message && message.length > 0) ||
-  "Le message ne peut pas être vide";
+  (!!message && message.length > 0) || 'Le message ne peut pas être vide'
 
 const validateMessageLength = (message: string | null) =>
   (!!message && message.length <= maxMessageLength) ||
-  "Le message ne doit pas dépasser " + maxMessageLength + " caractères";
+  'Le message ne doit pas dépasser ' + maxMessageLength + ' caractères'
 
-const contactRequestSent: Ref<boolean> = ref(false);
+const contactRequestSent: Ref<boolean> = ref(false)
+
+const errorMsg: Ref<string | null> = ref(null)
 
 /**
  * Submits the contact form.
@@ -284,43 +303,51 @@ const submit = async (): Promise<void> => {
     return
   }
 
-  await em.persist(ContactRequest, contactRequest)
+  try {
+    await em.persist(ContactRequest, contactRequest)
+  } catch (e) {
+    errorMsg.value =
+      "Une erreur s'est produite, nous sommes navrés pour le désagrément. Veuillez réessayer plus tard."
+    return
+  }
 
-  contactRequestSent.value = true;
+  contactRequestSent.value = true
+  errorMsg.value = null
 
   // Défile vers le début de page pour afficher le message de confirmation
-  setTimeout(
-    () => router.push({ path: '', hash: '#anchor' }),
-    30
-  )
-};
+  setTimeout(() => router.push({ path: '', hash: '#anchor' }), 30)
+}
 </script>
 
 <style scoped lang="scss">
+h4 {
+  display: flex;
+  flex-direction: row;
+  font-size: 40px;
+  line-height: 95px;
+  margin-bottom: 1rem;
+  align-items: center;
+  font-weight: 100;
+
+  @media (max-width: 600px) {
+    font-size: 24px;
+    line-height: 48px;
+  }
+
+  .line {
+    display: block;
+    height: 1px;
+    width: 64px;
+    min-width: 64px;
+    border-top: solid 1px var(--on-neutral-color);
+    margin-right: 18px;
+  }
+}
 
 .v-form {
   max-width: 1400px;
   margin: 0 auto;
 
-  h4 {
-    display: flex;
-    flex-direction: row;
-    font-size: 40px;
-    line-height: 95px;
-    margin-bottom: 1rem;
-    align-items: center;
-    font-weight: 100;
-
-    .line {
-      display: block;
-      height: 1px;
-      width: 64px;
-      min-width: 64px;
-      border-top: solid 1px var(--on-neutral-color);
-      margin-right: 18px;
-    }
-  }
-
   h6 {
     margin-top: 32px;
     font-size: 16px;
@@ -347,8 +374,20 @@ const submit = async (): Promise<void> => {
     font-weight: 600;
   }
 
+  .error {
+    color: red;
+    width: 80%;
+    margin: 0 auto 2em;
+    text-align: center;
+  }
+
   .legal {
     opacity: 0.7;
+    font-size: 14px;
+    font-style: italic;
+    margin-left: auto;
+    margin-right: auto;
+    max-width: 80%;
   }
 }
 

+ 42 - 43
components/Contact/Map.vue

@@ -1,17 +1,15 @@
 <template>
-<LayoutContainer>
-    <h4>
-      <span class="line" /> Contactez-nous
-    </h4>
+  <LayoutContainer>
+    <h4><span class="line" /> Contactez-nous</h4>
 
     <v-row>
-      <v-col cols="6">
+      <v-col cols="12" md="6">
         <div class="map-container">
           <l-map
             ref="map"
             :zoom="15"
             :center="location"
-            :options="{scrollWheelZoom: false}"
+            :options="{ scrollWheelZoom: false }"
           >
             <l-tile-layer
               url="https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png"
@@ -20,53 +18,48 @@
               attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>'
             />
 
-            <l-marker
-              :icon="icon"
-              :lat-lng="location"
-            />
-<!--              <l-popup>-->
-<!--                <v-row>-->
-<!--                  <v-col cols="4" class="d-flex align-center">-->
-<!--                    <v-img src="/images/Opentalent_Griffe.png"/>-->
-<!--                  </v-col>-->
-<!--                  <v-col cols="8">-->
-<!--                    <div>-->
-<!--                      OPENTALENT-->
-<!--                    </div>-->
-<!--                    <div>-->
-<!--                      217, rue Raoul Follereau-->
-<!--                    </div>-->
-<!--                    <div>-->
-<!--                      74300 - Cluses-->
-<!--                    </div>-->
-<!--                  </v-col>-->
-<!--                </v-row>-->
-<!--              </l-popup>-->
+            <l-marker :icon="icon" :lat-lng="location" />
+            <!--              <l-popup>-->
+            <!--                <v-row>-->
+            <!--                  <v-col cols="4" class="d-flex align-center">-->
+            <!--                    <v-img src="/images/Opentalent_Griffe.png"/>-->
+            <!--                  </v-col>-->
+            <!--                  <v-col cols="8">-->
+            <!--                    <div>-->
+            <!--                      OPENTALENT-->
+            <!--                    </div>-->
+            <!--                    <div>-->
+            <!--                      217, rue Raoul Follereau-->
+            <!--                    </div>-->
+            <!--                    <div>-->
+            <!--                      74300 - Cluses-->
+            <!--                    </div>-->
+            <!--                  </v-col>-->
+            <!--                </v-row>-->
+            <!--              </l-popup>-->
           </l-map>
         </div>
       </v-col>
 
-      <v-col class="infos">
-        <div class="name mb-8">
-          Opentalent
-        </div>
+      <v-col cols="12" md="6" class="infos">
+        <div class="name mb-8">Opentalent</div>
 
         <div class="d-flex flex-row align-center mb-8">
           <v-icon icon="fa fa-map-marker-alt" />
           <span>
-            217 rue Raoul Follereau<br/>
+            217 rue Raoul Follereau<br />
             74300 CLUSES
           </span>
         </div>
 
         <div class="d-flex flex-row mb-4">
           <v-icon icon="fa fa-phone" />
-          09.72.12.60.17
+          <a href="tel:+33972126017">09.72.12.60.17</a>
         </div>
 
         <div class="d-flex flex-row mb-4">
           <v-icon icon="far fa-envelope" />
-          contact@opentalent.fr
+          <a href="mailto:contact@opentalent.fr">contact@opentalent.fr</a>
         </div>
       </v-col>
     </v-row>
@@ -75,31 +68,34 @@
 
 <script setup lang="ts">
 import 'leaflet/dist/leaflet.css'
-import { LMap, LTileLayer, LMarker, LIcon } from '@vue-leaflet/vue-leaflet'
-import L from 'leaflet';
+import { LMap, LTileLayer, LMarker } from '@vue-leaflet/vue-leaflet'
+import L from 'leaflet'
 
 const location = [46.075245, 6.570162]
 
+// eslint-disable-next-line import/no-named-as-default-member
 const icon = L.icon({
-  iconUrl: '/images/contact/Pointeur_Opentalent.png',
+  iconUrl: '/images/pages/contact/map/Pointeur_Opentalent.png',
   iconSize: [80, 80],
   iconAnchor: [22, 94],
   popupAnchor: [5, -100],
 })
-
 </script>
 
 <style scoped lang="scss">
-
 h4 {
   display: flex;
   flex-direction: row;
   font-size: 40px;
   line-height: 95px;
+  margin-bottom: 1rem;
   align-items: center;
   font-weight: 100;
-  margin: 0 auto 1rem auto;
-  max-width: 1400px;
+
+  @media (max-width: 600px) {
+    font-size: 24px;
+    line-height: 48px;
+  }
 
   .line {
     display: block;
@@ -111,7 +107,6 @@ h4 {
   }
 }
 
-
 .map-container {
   height: 500px;
   width: 100%;
@@ -134,5 +129,9 @@ h4 {
     margin-right: 16px;
     opacity: 0.6;
   }
+
+  @media (max-width: 600px) {
+    order: -1
+  }
 }
 </style>

+ 0 - 0
components/Formation/Banner.vue


+ 77 - 96
components/Formation/Catalogue.vue

@@ -6,17 +6,11 @@
           Découvrez notre catalogue de formation
         </LayoutUISubTitle>
 
-        <LayoutUITitle class="ml-8">
-          Catalogue
-        </LayoutUITitle>
+        <LayoutUITitle class="ml-8"> Catalogue </LayoutUITitle>
       </v-row>
 
       <v-row class="center-90 catalog">
-        <v-col
-          v-for="(course, index) in courses"
-          :key="index"
-          cols="4"
-        >
+        <v-col v-for="(course, index) in courses" :key="index" cols="12" lg="4">
           <v-card class="mb-4">
             <v-card-text>
               <div class="title-card-container">
@@ -34,9 +28,7 @@
               </p>
 
               <div class="objectives">
-                <h6 class="title-obj">
-                  Objectifs pédagogiques
-                </h6>
+                <h6 class="title-obj">Objectifs pédagogiques</h6>
 
                 <ul>
                   <li
@@ -48,10 +40,10 @@
                 </ul>
               </div>
 
+              <div class="badge-time">Durée : {{ course.duration }}</div>
+
               <div class="program">
-                <h6 class="title-obj">
-                  Programme
-                </h6>
+                <h6 class="title-obj">Programme</h6>
 
                 <v-row>
                   <v-col
@@ -71,17 +63,9 @@
                 </v-row>
               </div>
 
-              <v-chip class="badge-time">
-                <span>
-                  Durée : {{ course.duration }}
-                </span>
-              </v-chip>
-
-              <v-chip class="badge-time">
-                <span>
-                  {{ course.price }}
-                </span>
-              </v-chip>
+              <div class="badge-time">
+                {{ course.price }}
+              </div>
 
               <v-chip
                 class="chip-register"
@@ -98,117 +82,114 @@
 </template>
 
 <script setup lang="ts">
-import { useDisplay } from "vuetify";
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { Training } from "~/types/interface";
-
-const { mdAndDown } = useDisplay();
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { Training } from '~/types/interface'
 
 const downloadPdf = (pdfUrl: string) => {
-  window.open(pdfUrl, "_blank");
-};
+  window.open(pdfUrl, '_blank')
+}
 
 const courses: Array<Training> = [
   {
-    number: "01",
-    title: "Formation initiale ",
+    number: '01',
+    title: 'Formation initiale',
     description:
       "Cette formation est destinée aux nouveaux utilisateurs. Elle est obligatoire lors de l'acquisition du logiciel. Elle est également utile lors d'un changement de personnel dans la structure. ",
     objectives: [
-      "Ajuster la configuration du logiciel",
-      "Gérer les élèves et leurs familles",
-      "Générer des factures et faire le suivi des règlements",
-      "Gérer le planning des cours",
-      "Évaluer les élèves et générer des bulletins",
-      "Communiquer avec les personnes du répertoire",
+      'Ajuster la configuration du logiciel',
+      'Gérer les élèves et leurs familles',
+      'Générer des factures et faire le suivi des règlements',
+      'Gérer le planning des cours',
+      'Évaluer les élèves et générer des bulletins',
+      'Communiquer avec les personnes du répertoire',
     ],
-    duration: "14h",
+    duration: '14h',
     program: [
       {
         id: 1,
         objectives: [
-          "Accès et interface",
-          "Configuration",
-          "Répertoire",
-          "Agenda",
+          'Accès et interface',
+          'Configuration',
+          'Répertoire',
+          'Agenda',
         ],
       },
       {
         id: 2,
         objectives: [
-          "Parc matériel",
-          "Suivi pédagogique",
-          "Facturation",
-          "Communication",
+          'Parc matériel',
+          'Suivi pédagogique',
+          'Facturation',
+          'Communication',
         ],
       },
     ],
-    price: "1 580 € TTC",
+    price: '2 008,80€ TTC',
     downloadLink:
-      "https://www.opentalent.fr/fileadmin/stockage/stockage/support/programme/PF-School-2023-02_2-jours.pdf",
+      'public/files/PF-School-2024-02_2-jours.pdf',
   },
   {
-    number: "02",
-    title: "Formation complémentaire",
+    number: '02',
+    title: 'Formation complémentaire',
     // imageUrl: "/images/opentalent_school_black.jpg",
     description:
-      "Cette formation suppose d’avoir les connaissances de base sur le logiciel. Elle permet d’avoir une remise à niveau sur sur des fonctionnalités qui ont été incorrectement comprises / configurées, ou qui ont été récemment développées.",
+      'Cette formation suppose d’avoir les connaissances de base sur le logiciel. Elle permet d’avoir une remise à niveau sur sur des fonctionnalités qui ont été incorrectement comprises / configurées, ou qui ont été récemment développées.',
     objectives: [
-      "Ajuster la configuration du logiciel",
-      "Gérer les élèves et leurs familles",
+      'Ajuster la configuration du logiciel',
+      'Gérer les élèves et leurs familles',
     ],
-    duration: "7h",
+    duration: '7h',
     program: [
       {
         id: 1,
-        objectives: ["Accès et interface", "Configuration"],
+        objectives: ['Accès et interface', 'Configuration'],
       },
       {
         id: 2,
-        objectives: ["Répertoire"],
+        objectives: ['Répertoire'],
       },
     ],
-    price: "790€ TTC",
+    price: '1004,40€ TTC',
     downloadLink:
-      "https://www.opentalent.fr/fileadmin/stockage/stockage/support/programme/PF-School-2023-02_1-jour.pdf",
+      'public/files/PF-School-2024-02_1-jour.pdf',
   },
   {
-    number: "03",
-    title: "Formation Typo 3",
+    number: '03',
+    title: 'Formation Typo 3',
     // imageUrl: "/images/opentalent_school_black.jpg",
     description:
       "Cette formation est destinée aux nouveaux utilisateurs Typo3. Elle est optionnelle et permet d'aller plus loin dans la gestion du site internet intégré.",
     objectives: [
-      "Gérer les pages et leur accès",
-      "Gérer le contenu des pages et leur accès",
-      "Configurer les options du site internet côté logiciel",
+      'Gérer les pages et leur accès',
+      'Gérer le contenu des pages et leur accès',
+      'Configurer les options du site internet côté logiciel',
     ],
-    duration: "7h",
+    duration: '7h',
     program: [
       {
         id: 1,
-        objectives: ["Gestion des pages", "Gestion des blocs"],
+        objectives: ['Gestion des pages', 'Gestion des blocs'],
       },
       {
         id: 2,
-        objectives: ["Configuration côté logiciel"],
+        objectives: ['Configuration côté logiciel'],
       },
     ],
-    price: "790€ TTC",
+    price: '1004,40€ TTC',
     downloadLink:
-      " https://www.opentalent.fr/fileadmin/stockage/stockage/support/programme/PF-Typo3-2023-02_1-jour.pdf",
+      'public/files/PF-Typo3-2024-02_1-jour.pdf',
   },
-];
+]
 </script>
 
-<style scoped>
-
-* {
-  text-align: justify;
-}
-
+<style scoped lang="scss">
 .catalog {
   padding: 2rem;
+  background: var(--neutral-color-alt-light);
+
+  @media (max-width: 600px) {
+    padding: 0.5rem;
+  }
 
   .v-card {
     border: none !important;
@@ -230,7 +211,7 @@ const courses: Array<Training> = [
     .number-card {
       font-weight: 500;
       font-size: 1.3rem;
-      color: var(--secondary-color);
+      color: var(--primary-color);
       margin-right: 1rem;
     }
   }
@@ -241,14 +222,15 @@ const courses: Array<Training> = [
     line-height: 1rem;
     color: var(--primary-color);
     margin-top: 1rem;
-    margin-bottom: .5rem;
+    margin-bottom: 0.5rem;
     height: 5rem;
   }
 
-  .objectives, .program {
+  .objectives,
+  .program {
     justify-content: space-between;
     align-items: center;
-    background: var(--secondary-color);
+    background: var(--secondary-color-light);
     margin-top: 1rem;
     margin-bottom: 1rem;
     border-radius: 1rem;
@@ -268,24 +250,23 @@ const courses: Array<Training> = [
       font-size: 14px;
       line-height: 18px;
     }
+
+    @media (max-width: 600px) {
+      height: auto;
+    }
   }
 
   .badge-time {
-    color: var(--on-primary-color);
-    border: 1px solid var(--primary-color);
-    border-radius: 3rem;
+    color: var(--primary-color);
+    background: var(--neutral-color);
+    width: 100%;
+    height: 36px;
+    text-align: center;
+    font-size: 18px;
     font-weight: 500;
-    font-size: 14px;
-    line-height: 18px;
-    margin-top: 1rem;
-    margin-bottom: 1rem;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-
-    span {
-      color: var(--primary-color);
-    }
+    border-radius: 12px;
+    vertical-align: center;
+    padding-top: 6px;
   }
 
   .chip-register {

+ 23 - 8
components/Formation/Certification.vue

@@ -2,16 +2,14 @@
   <AnchoredSection id="certification">
     <LayoutContainer>
       <v-row class="center-90">
-        <v-col cols="5">
-          <LayoutUISubTitle>
-            DES FORMATIONS CERTIFIÉES
-          </LayoutUISubTitle>
+        <v-col cols="12" md="5">
+          <LayoutUISubTitle> DES FORMATIONS CERTIFIÉES </LayoutUISubTitle>
 
           <LayoutUITitle>
             Certification Qualiopi : Marque de certification
           </LayoutUITitle>
 
-          <div class="bloc-certif ml-12 mt-6 mr-12">
+          <div class="bloc-certif">
             <p>
               Nos formations sont certifiées Qualiopi - Actions de formation.
             </p>
@@ -34,8 +32,11 @@
           </div>
         </v-col>
 
-        <v-col cols="7">
-          <v-img src="/images/formation/qualiopi.jpg" />
+        <v-col cols="12" md="7" class="image-container">
+          <v-img
+            src="/images/logos/qualiopi/Logo-Qualiopi_Processus_Certifié-Republique_Française.png"
+            alt="Deux personnes en train d’échanger sur un projet devant deux ordinateurs dans un open space"
+          />
         </v-col>
       </v-row>
     </LayoutContainer>
@@ -43,12 +44,13 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
 </script>
 
 <style scoped lang="scss">
 .bloc-certif {
   text-align: justify;
+  margin: 18px;
 }
 
 ul {
@@ -57,6 +59,7 @@ ul {
   line-height: 20px;
   color: var(--primary-color);
   margin-top: 1rem;
+  margin-left: 22px;
 }
 
 .details-certifications {
@@ -66,4 +69,16 @@ ul {
   color: var(--primary-color);
   margin-top: 1rem;
 }
+
+.image-container {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+
+  .v-img {
+    width: 80%;
+    max-width: 500px;
+    margin: auto;
+  }
+}
 </style>

+ 15 - 10
components/Formation/OPCA.vue

@@ -2,22 +2,21 @@
   <AnchoredSection id="financing">
     <LayoutContainer class="alt-theme py-6 my-6">
       <v-row class="center-90">
-        <LayoutUISubTitle>
-          Financement des formations
-        </LayoutUISubTitle>
+        <LayoutUISubTitle> Financement des formations </LayoutUISubTitle>
       </v-row>
 
       <v-container>
         <v-row class="align-center center-90">
-          <v-col cols="6">
+          <v-col cols="12" md="6">
             <v-img
-              src="/images/formation/programme.jpg"
+              src="/images/pages/formations/opca/Formations_eligibles_aux_OPCA.jpg"
+              alt="Hommes discutant devant des ordinateurs"
               class="opca-img"
               cover
             />
           </v-col>
 
-          <v-col cols="12" md="6" lg="6">
+          <v-col cols="12" md="6">
             <v-row>
               <h3 class="mt-6 mb-6 mr-6">
                 Des formations éligibles par votre OPCA
@@ -52,14 +51,14 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
 </script>
 
 <style scoped lang="scss">
 .opca-img {
-  height: 400px;
-  width: 450px;
+  width: 80%;
   border-radius: 10%;
+  margin: 16px 20% 16px 0;
 }
 
 h3 {
@@ -76,6 +75,12 @@ h3 {
   color: var(--on-primary-color);
   width: 100%;
   margin: auto;
-  text-align: justify;
+}
+
+@media (max-width: 1240px) {
+  .v-img {
+    margin-left: auto;
+    margin-right: auto;
+  }
 }
 </style>

+ 21 - 25
components/Formation/Participation.vue

@@ -3,27 +3,25 @@
     <LayoutContainer class="alt-theme">
       <v-row class="center-90">
         <v-col cols="12">
-          <LayoutUISubTitle>
-            Accessibilité
-          </LayoutUISubTitle>
+          <LayoutUISubTitle> Accessibilité </LayoutUISubTitle>
         </v-col>
       </v-row>
 
-      <h3 class="title-participation text-center mb-8">
-        Vous souhaitez participer à une formation ?
-      </h3>
-
       <v-row class="mb-12 center-90">
-        <v-col cols="12">
+        <v-col cols="12" lg="6">
           <v-img
-            src="/images/formation/participation.jpg"
+            src="/images/pages/formations/accessibilite/Formations_accessibles_a_tous.jpg"
+            alt="Ordinateur avec un écran en visioconférence avec plusieurs personnes posé sur une table avec un pichet posé à côté"
             class="participation-img"
+            cover
           />
         </v-col>
-      </v-row>
 
-      <v-row class="mb-12 center-90">
-        <v-col cols="12">
+        <v-col cols="12" lg="4">
+          <h3 class="title-participation text-center mb-8">
+            Vous souhaitez participer à une formation ?
+          </h3>
+
           <div class="details-participations">
             <p class="mb-6">
               Nous vous répondons sous 48h (hors week-ends). Délais d'accès:
@@ -56,7 +54,7 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
 </script>
 
 <style scoped lang="scss">
@@ -71,12 +69,6 @@ import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
   margin-right: auto;
 }
 
-@media (min-width: 1200px) {
-  .v-row {
-    min-width: 100%;
-  }
-}
-
 .icon-title {
   font-size: 1rem;
   margin-right: 1rem;
@@ -99,27 +91,31 @@ h3 {
 .details-participations {
   display: flex;
   flex-direction: column;
-  text-align: justify;
   font-weight: 300;
   font-size: 16px;
   line-height: 20px;
   margin: 1rem auto auto auto;
   width: 800px;
+  max-width: 100%;
   color: var(--on-primary-color);
 }
 
 .participation-img {
   position: relative;
-  background-image: url("/images/formation/participation.jpg");
-  width: 700px;
-  height: 550px;
   background-position: center;
   background-size: cover;
   border-radius: 10%;
   display: flex;
   justify-content: center;
   align-items: center;
-  margin-left: auto;
-  margin-right: auto;
+  width: 80%;
+  margin: 16px 20% 16px 0;
+}
+
+@media (max-width: 1240px) {
+  .v-img {
+    margin-left: auto;
+    margin-right: auto;
+  }
 }
 </style>

+ 26 - 15
components/Formation/Presentation.vue

@@ -2,19 +2,19 @@
   <AnchoredSection id="presentation">
     <LayoutContainer>
       <v-row class="mt-6 center-90">
-        <LayoutUISubTitle>
-          Présentation de nos formations
-        </LayoutUISubTitle>
+        <LayoutUISubTitle> Présentation de nos formations </LayoutUISubTitle>
       </v-row>
 
       <v-row class="mb-12 center-90">
-        <v-col cols="6">
+        <v-col md="6">
           <v-img
-            src="/images/formation/programme2.jpg"
-            class="programme-img1"/>
+            src="/images/pages/formations/presentation/Un_programme_de_formation_complet_sur_nos_logiciels_Opentalent.jpg"
+            alt="Mains tapant sur un clavier d’ordinateur portable"
+            class="programme-img1"
+          />
         </v-col>
 
-        <v-col cols="6">
+        <v-col md="6">
           <h3 class="title-programme mb-6">
             Un programme de formation complet sur nos logiciels
           </h3>
@@ -39,7 +39,7 @@
       </v-row>
 
       <v-row class="center-90">
-        <v-col cols="6">
+        <v-col md="6">
           <h3 class="title-programme mb-6 mt-4">
             Des formations à la demande et sur-mesure
           </h3>
@@ -52,9 +52,10 @@
           </p>
         </v-col>
 
-        <v-col cols="6">
+        <v-col md="6">
           <v-img
-            src="/images/formation/programme.jpg"
+            src="/images/pages/formations/presentation/Des_formations_sur-mesure.jpg"
+            alt="Deux personnes en train d’échanger sur un projet devant deux ordinateurs dans un open space"
             class="programme-img2"
           />
         </v-col>
@@ -64,18 +65,29 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
 </script>
 
 <style scoped lang="scss">
 .v-img {
-  width: 80%;
+  width: 560px;
   height: 100%;
   border-radius: 10%;
+
+  @media (max-width: 600px) {
+    margin-left: auto;
+    margin-right: auto;
+  }
 }
 
-h3, p {
-    width: 35rem;
+h3,
+p {
+  width: 35rem;
+  max-width: 100%;
+
+  @media (max-width: 1240px) {
+    width: 100%;
+  }
 }
 
 h3 {
@@ -88,7 +100,6 @@ p {
   font-weight: 300;
   font-size: 1.2rem;
   line-height: 20px;
-  text-align: justify;
 }
 
 .school {

+ 16 - 16
components/Formation/Reviews.vue

@@ -7,37 +7,37 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { Review } from "~/types/interface";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { Review } from '~/types/interface'
 
 const cards: Array<Review> = [
   {
     review:
-      "Formation très personnalisée et très productive. Tout à fait adaptée à nos besoins actuels.",
-    name: "Jocelyne DELAPORTE ",
-    status: "Responsable administrative",
-    structure: "École de Musique Municipale De Pecquencourt (59)",
+      'Formation très personnalisée et très productive. Tout à fait adaptée à nos besoins actuels.',
+    name: 'Jocelyne DELAPORTE ',
+    status: 'Responsable administrative',
+    structure: 'École de Musique Municipale De Pecquencourt (59)',
   },
   {
     review:
       "Merci à Johan d'avoir pris le temps de nous former, de rentrer dans les détails des questions abordées. Et merci à l'équipe pour votre réactivité lorsque l'on demande à être aidés",
-    name: "Claire CAGNON ",
-    status: "Secrétaire administrative",
-    structure: "École de Musique, Théâtre et Cirque Alsace Rhin Brisach (68)",
+    name: 'Claire CAGNON ',
+    status: 'Secrétaire administrative',
+    structure: 'École de Musique, Théâtre et Cirque Alsace Rhin Brisach (68)',
   },
   {
     review:
-      " Une journée de formation précieuse pour un point complet de la prise en main du logiciel et des réponses utiles aux questions et problématiques rencontrées.",
-    name: "Sayuri OKA NICOLEAU",
-    status: "Directrice administrative & pédagogique",
-    structure: "École Municipale de Musique de Croissy-sur-Seine (78)",
+      ' Une journée de formation précieuse pour un point complet de la prise en main du logiciel et des réponses utiles aux questions et problématiques rencontrées.',
+    name: 'Sayuri OKA NICOLEAU',
+    status: 'Directrice administrative & pédagogique',
+    structure: 'École Municipale de Musique de Croissy-sur-Seine (78)',
   },
   {
     review:
       "Un formateur à l'écoute des besoins de notre structure et des besoins de nous deux débutants sur le logiciel. Besoin compris pour une journée de formation complémentaire pour lancer la campagne d'inscription courant le deuxième trimestre 2022. Merci pour la patience de Johan, pédagogue et fin connaisseur de son logiciel.",
-    name: "Alain BATS",
-    status: "Président adjoint",
+    name: 'Alain BATS',
+    status: 'Président adjoint',
     structure: "L'École Intercommunale de Musique LEIM (74)",
   },
-];
+]
 </script>

+ 33 - 17
components/Home/Besoin.vue

@@ -1,20 +1,16 @@
 <template>
   <LayoutContainer>
-    <v-row
-      v-if="!mdAndDown"
-      class="mt-6"
-      justify="center"
-    >
-      <v-col cols="6">
+    <v-row class="mt-6" justify="center">
+      <v-col cols="12" lg="6">
         <div class="screen-img ml-4" />
       </v-col>
 
-      <v-col cols="6" >
+      <v-col cols="12" lg="6" class="detail-col">
         <h3 class="mt-12">
           Une solution évolutive pour vous donner entière satisfaction
         </h3>
 
-        <p class="details ">
+        <p class="details">
           La satisfaction de nos clients est notre première motivation et nous
           nous tenons à votre écoute pour faire évoluer notre logiciel. <br />
           <b>Un besoin ?</b> <br />
@@ -27,15 +23,11 @@
   </LayoutContainer>
 </template>
 
-<script setup lang="ts">
-  import { useDisplay } from "vuetify";
-  const { mdAndDown } = useDisplay();
-</script>
+<script setup lang="ts"></script>
 
 <style scoped lang="scss">
-.v-row
-{
-  margin-left:auto !important;
+.v-row {
+  margin-left: auto !important;
   margin-right: auto !important;
   max-width: 1400px !important;
 }
@@ -57,14 +49,38 @@ p {
   margin-left: 2rem;
   color: var(--primary-color);
   width: 20rem;
-  text-align: justify;
 }
 
 .screen-img {
-  background-image: url("/images/home/Repondre-aux-besoins-des-clients-Opentalent.png");
+  background-image: url('/images/pages/home/besoin/Repondre-aux-besoins-des-clients-Opentalent.png');
   background-position: center;
   background-size: cover;
   width: 700px;
   height: 500px;
+
+  @media (max-width: 1240px) {
+    width: 90%;
+    height: 400px;
+  }
+
+  @media (max-width: 600px) {
+    height: 240px;
+  }
+}
+
+.detail-col {
+  @media (max-width: 1240px) {
+    * {
+      width: 80%;
+      margin: auto;
+      text-align: justify;
+    }
+
+    h3 {
+      margin-bottom: 16px;
+      text-align: center;
+      font-weight: 600;
+    }
+  }
 }
 </style>

+ 175 - 116
components/Home/Caroussel.vue

@@ -2,154 +2,177 @@
 Carrousel de la page d'accueil
 -->
 <template>
-  <v-carousel
-    ref="carousel"
-    v-model="activeIndex"
-    :show-arrows="false"
-    :hide-delimiter-background="true"
-    :show-delimiters="false"
-    :touch="true"
-    :wrap-around="true"
-    :interval="5000"
-  >
-    <v-carousel-item
-      v-for="(item, index) in carouselItems"
-      :key="index"
+  <div v-intersect="onIntersect">
+    <v-carousel
+      ref="carousel"
+      v-model="activeIndex"
+      :show-arrows="false"
+      :hide-delimiter-background="true"
+      :show-delimiters="false"
+      :touch="true"
+      :height="lgAndUp ? 500 : 800"
+      :interval="10000"
+      :cycle="true"
     >
-      <v-row>
-        <!-- Partie description (logo, description, bouton 'en savoir plus') -->
-        <v-col cols="12" lg="6" class="col presentation">
-          <v-img
-            :src="item.logo"
-            class="logo"
-          />
-
-          <p class="description" v-html="item.description" />
+      <v-carousel-item v-for="(item, index) in carouselItems" :key="index">
+        <v-row>
+          <!-- Partie description (logo, description, bouton 'en savoir plus') -->
+          <v-col cols="12" lg="6" class="col presentation">
+            <nuxt-link :to="item.link">
+              <v-img :src="item.logo" :alt="item.logoAlt" class="logo" />
+            </nuxt-link>
+
+            <p
+              class="description"
+              v-html="mdAndUp ? item.description : item.descriptionSm"
+            />
 
-          <v-row class="align-start pl-4">
             <v-btn
               :to="item.link"
               append-icon="fas fa-arrow-right"
-              :class="['learn-more-btn', item.buttonClass]"
+              :class="['mt-3 learn-more-btn', item.buttonClass]"
             >
               En savoir plus
             </v-btn>
-          </v-row>
-        </v-col>
-
-        <!-- Partie Illustration -->
-        <v-col cols="12" lg="6" class="col illustration">
-          <v-row>
-            <div
-              class="background-rectangle"
-              :style="{ backgroundColor: item.color }"
-            />
-
-            <v-card class="card" elevation="5">
-              <v-img
-                class="profile-image"
-                :src="item.avatar"
-                alt="Profile Image"
-                contain
-                rounded
+          </v-col>
+
+          <!-- Partie Illustration -->
+          <v-col cols="12" lg="6" class="col illustration">
+            <v-row>
+              <div
+                class="background-rectangle"
+                :style="{ backgroundColor: item.color }"
               />
-              <v-card-text>
-                <v-card-title class="name">
-                  {{ item.name }}
 
-                  <p class="school">
-                    {{ item.school }}
+              <v-card class="card" elevation="5">
+                <v-img
+                  class="profile-image"
+                  :src="item.avatar"
+                  :alt="item.avatarAlt"
+                  contain
+                  rounded
+                />
+                <v-card-text>
+                  <v-card-title class="name">
+                    {{ item.name }}
+
+                    <p class="school">
+                      {{ item.school }}
+                    </p>
+                  </v-card-title>
+
+                  <p class="status">
+                    {{ item.status }}
                   </p>
-                </v-card-title>
-
-                <p class="status">
-                  {{ item.status }}
-                </p>
-              </v-card-text>
-            </v-card>
-
-            <v-img
-              :src="item.image"
-              :class="smAndDown ? 'image-sm' : 'image'"
-            />
-          </v-row>
-        </v-col>
-      </v-row>
-    </v-carousel-item>
-
-    <div class="custom-controls">
-      <!--suppress JSUnusedLocalSymbols -->
-      <div
-        v-for="(_, index) in carouselItems"
-        :key="index"
-        :class="{ 'active-control': index === activeIndex }"
-        @click="setActiveIndex(index)"
-      />
-    </div>
-  </v-carousel>
+                </v-card-text>
+              </v-card>
+
+              <v-img :src="item.image" :alt="item.imageAlt" class="image" />
+            </v-row>
+          </v-col>
+        </v-row>
+      </v-carousel-item>
+
+      <div class="custom-controls">
+        <!--suppress JSUnusedLocalSymbols -->
+        <div
+          v-for="(_, index) in carouselItems"
+          :key="index"
+          :class="{ 'active-control': index === activeIndex }"
+          @click="setActiveIndex(index)"
+        />
+      </div>
+    </v-carousel>
+  </div>
 </template>
 
 <script setup lang="ts">
+import { useDisplay } from 'vuetify'
+import type { Ref } from 'vue'
+import type { CarouselItem } from '~/types/interface'
+import { useLayoutStore } from '~/stores/layoutStore'
 
-import { useDisplay } from "vuetify";
-import type { CarouselItem } from "~/types/interface";
-const { smAndDown, mdAndDown } = useDisplay();
+const { mdAndUp, lgAndUp } = useDisplay()
 
 // Index de la slide active
-let activeIndex: Ref<number> = ref(0);
+const activeIndex: Ref<number> = ref(0)
 
 const setActiveIndex = (index: number) => {
-  activeIndex.value = index;
-};
+  activeIndex.value = index
+}
 
 const carouselItems: Ref<Array<CarouselItem>> = ref([
   {
-    logo: "/images/logo/logiciels/School-noir.png",
+    logo: '/images/logos/opentalent/Logo_Opentalent_School-gris.png',
+    logoAlt:
+      'Logo Opentalent School - logiciel de gestion et de communication pour les établissements d’enseignement artistique',
     description:
       "Pour les petits comme pour les GRANDS établissements d’enseignement artistique tels que les écoles de musique, de danse, de théâtre, d'art, de cirque et conservatoire.<br> Il permet la gestion au quotidien et en temps réel de votre établissement, de gérer vos élèves et vos professeurs, vos emplois du temps, le suivi pédagogique, vos salles, la facturation et les encaissements…",
-    buttonClass: "btn-school",
+    descriptionSm:
+      "Pour les petits comme pour les GRANDS établissements d’enseignement artistique tels que les écoles de musique, de danse, de théâtre, d'art, de cirque et conservatoire.",
+    buttonClass: 'btn-school',
     image:
-      "/images/Home_logiciel/Logiciel_Opentalent_School-eleve-Conservatoire_de_Musique.png",
-    color: "rgba(32, 147, 190, 0.4)",
-    link: "/opentalent_school",
-    name: "Cindy Blanchard",
-    school: "Conservatoire de Musique",
-    status: "élève",
-    avatar: "/images/carousel/school/avatar.png",
+      '/images/pages/home/carousel/Logiciel_Opentalent_School-eleve-Conservatoire_de_Musique.png',
+    imageAlt: 'Jeune élève de batterie',
+    color: 'rgba(32, 147, 190, 0.4)',
+    link: '/opentalent_school',
+    name: 'Cindy Blanchard',
+    school: 'Conservatoire de Musique',
+    status: 'élève',
+    avatar: '/images/pages/home/carousel/Photo_de_profil_d_une_jeune_fille.png',
+    avatarAlt: 'Photo de profil d’une jeune fille',
   },
   {
-    logo: "/images/logo/logiciels/Artist-noir.png",
+    logo: '/images/logos/opentalent/Logo_Opentalent_Artist-gris.png',
+    logoAlt:
+      'Logo Opentalent Artist - logiciel de gestion et de communication pour les orchestres, les chorales, les compagnies artistiques et troupes',
     description:
-      "Pour les structures culturelles pratiquantes telles que les orchestres, les chorales, les compagnies de danse, théâtre et cirque. <br> Gérez votre activité avec un logiciel de gestion et de communication au service de votre passion.",
-    buttonClass: "btn-artist",
+      'Pour les structures culturelles pratiquantes telles que les orchestres, les chorales, les compagnies de danse, théâtre et cirque. <br> Gérez votre activité avec un logiciel de gestion et de communication au service de votre passion.',
+    descriptionSm:
+      'Pour les structures culturelles pratiquantes telles que les orchestres, les chorales, les compagnies de danse, théâtre et cirque.',
+    buttonClass: 'btn-artist',
     image:
-      "/images/Home_logiciel/Logiciel_Opentalent_Artist-administrateur-Orchestre_d_harmonie.png",
-    color: "rgba(250, 194, 10, 0.4)",
-    link: "opentalent_artist",
-    name: "Thierry Dupont ",
-    school: "Orchestre d’harmonie",
-    status: "Admin",
-    avatar: "/images/carousel/artist/avatar.png",
+      '/images/pages/home/carousel/Logiciel_Opentalent_Artist-administrateur-Orchestre_d_harmonie.png',
+    imageAlt: 'Homme jouant du banjo',
+    color: 'rgba(250, 194, 10, 0.4)',
+    link: 'opentalent_artist',
+    name: 'Thierry Dupont ',
+    school: 'Orchestre d’harmonie',
+    status: 'Admin',
+    avatar:
+      '/images/pages/home/carousel/Photo_de_profil_d_un_homme_jouant_du_banjo.png',
+    avatarAlt: 'Photo de profil d’un homme jouant du banjo',
   },
   {
-    logo: "/images/logo/logiciels/Manager-noir.png",
+    logo: '/images/logos/opentalent/Logo_Opentalent_Manager-gris.png',
+    logoAlt:
+      'Logo Opentalent Manager - logiciel de gestion et de communication pour les fédérations, les confédérations et les collectivités',
     description:
-      "La solution de mise en réseau des organisations culturelles.<br> Fédérations, confédérations et collectivités, utilisez une solution collaborative innovante et unique spécialement développée pour les réseaux culturels.",
-    buttonClass: "btn-manager",
+      'La solution de mise en réseau des organisations culturelles.<br> Fédérations, confédérations et collectivités, utilisez une solution collaborative innovante et unique spécialement développée pour les réseaux culturels.',
+    descriptionSm:
+      'La solution de mise en réseau des organisations culturelles, telles que les fédérations, confédérations et collectivités.',
+    buttonClass: 'btn-manager',
     image:
-      "/images/Home_logiciel/Logiciel_Opentalent_Managerl-Administrateur_Federation.png",
-    color: "rgba(216, 5, 11, 0.4)",
-    link: "opentalent_manager",
-    name: "Marie Voisin",
+      '/images/pages/home/carousel/Logiciel_Opentalent_Manager-Administrateur_Federation.png',
+    imageAlt: 'Un homme en costard et une femme tailleur souriant',
+    color: 'rgba(216, 5, 11, 0.4)',
+    link: 'opentalent_manager',
+    name: 'Marie Voisin',
     school: "Réseau d'organisations culturelles ",
-    status: "ADMIN",
-    avatar: "/images/carousel/manager/avatar.png",
+    status: 'ADMIN',
+    avatar:
+      '/images/pages/home/carousel/Photo_de_profil_d_une_femme_en_tailleur.png',
+    avatarAlt: 'Photo de profil d’une femme en tailleur',
   },
-]);
+])
+
+const layoutStore = useLayoutStore()
+const onIntersect = (isIntersecting: boolean) => {
+  layoutStore.setIsBannerVisible(isIntersecting)
+}
 </script>
 
 <style scoped lang="scss">
-
 /* ============= CAROUSEL ===============  */
 :deep(.v-carousel__controls) {
   display: none;
@@ -181,16 +204,24 @@ const carouselItems: Ref<Array<CarouselItem>> = ref([
 
 /* ============= Colonne gauche - Description ===============  */
 .col.presentation {
+  padding-left: 7rem;
+
+  @media (max-width: 600px) {
+    padding-left: 0;
+  }
+
   .logo {
     width: 20rem;
     margin-top: 10px;
-    margin-left: 6rem;
+
+    @media (max-width: 600px) {
+      width: 15rem;
+      margin-left: 1rem;
+    }
   }
 
   .description {
-    text-align: justify;
     margin-top: 8px;
-    margin-left: 7rem;
     width: 25vw;
     margin-bottom: 1rem;
   }
@@ -207,7 +238,11 @@ const carouselItems: Ref<Array<CarouselItem>> = ref([
     line-height: 15px;
     width: 10rem;
     height: 2.5rem;
-    margin-left: 7rem;
+
+    @media (max-width: 600px) {
+      width: 80%;
+      margin: 15px auto;
+    }
   }
 
   .learn-more-btn :deep(.v-btn__append) {
@@ -226,13 +261,24 @@ const carouselItems: Ref<Array<CarouselItem>> = ref([
   .btn-manager {
     background: var(--manager-color-light);
   }
+
+  @media (max-width: 1280px) {
+    padding-bottom: 48px;
+    min-height: 50%;
+
+    .description {
+      width: 80%;
+      margin-left: auto;
+      margin-right: auto;
+    }
+  }
 }
 
 /* ============= Colonne droite - Illustration ===============  */
 .col.illustration {
   .card {
     position: relative;
-    left: 10%;
+    left: 5%;
     height: 100%;
     width: 27%;
     border-radius: 1rem;
@@ -251,7 +297,8 @@ const carouselItems: Ref<Array<CarouselItem>> = ref([
     padding: 0 !important;
   }
 
-  .school, .status {
+  .school,
+  .status {
     text-align: center;
     white-space: normal;
   }
@@ -287,5 +334,17 @@ const carouselItems: Ref<Array<CarouselItem>> = ref([
     height: 35rem;
     right: 5rem;
   }
+
+  @media (max-width: 1280px) {
+    .background-rectangle {
+      top: 60%;
+      height: 14rem;
+    }
+
+    .image {
+      height: 20rem;
+      right: 0;
+    }
+  }
 }
 </style>

+ 81 - 42
components/Home/EventAgenda.vue

@@ -4,62 +4,67 @@ Section "Agenda" de la page d'accueil
 <template>
   <LayoutContainer>
     <div class="container">
+      <div class="d-flex flex-row justify-center">
+        <h2 class="alt-theme bg-transparent">
+          L’agenda Opentalent
+        </h2>
+      </div>
+
       <div class="d-flex align-center justify-center">
         <h3>
-          Retrouvez tous vos évènements dans l'agenda et référencez vous dans
-          l'annuaire
+          Retrouvez tous les événements et toutes les structures culturelles
+          autour de chez vous
         </h3>
       </div>
 
-      <v-row justify="center">
-        <div class="btn-container">
-          <v-col cols="12" md="6">
-            <AgendaLink href="/">
-              <v-btn
-                append-icon="fas fa-arrow-right"
-                class="btn-event"
-              >
-                Découvrir l'agenda
-              </v-btn>
-            </AgendaLink>
-          </v-col>
-
-          <v-col cols="12" md="6">
-            <AgendaLink href="/annuaire">
-              <v-btn
-                append-icon="fas fa-arrow-right"
-                class="btn-event"
-              >
-                Découvrir l’annuaire
-              </v-btn>
-            </AgendaLink>
-          </v-col>
-        </div>
+      <v-row justify="center" class="btn-container">
+        <v-col cols="12" lg="6">
+          <AgendaLink href="/">
+            <v-btn append-icon="fas fa-arrow-right" class="btn-event">
+              Découvrir l'agenda
+            </v-btn>
+          </AgendaLink>
+        </v-col>
+
+        <v-col cols="12" lg="6">
+          <AgendaLink href="/annuaire">
+            <v-btn
+              append-icon="fas fa-arrow-right"
+              :variant="lgAndUp ? 'elevated' : 'outlined'"
+              class="btn-event btn-annuaire"
+            >
+              Découvrir l’annuaire
+            </v-btn>
+          </AgendaLink>
+        </v-col>
       </v-row>
     </div>
   </LayoutContainer>
 </template>
 
 <script setup>
-import { useDisplay } from "vuetify";
-import AgendaLink from "~/components/Common/AgendaLink.vue";
-const { mdAndDown } = useDisplay();
+import { useDisplay } from 'vuetify'
+import AgendaLink from '~/components/Common/AgendaLink.vue'
+const { lgAndUp } = useDisplay()
 </script>
 
 <style scoped>
-
-@media (min-width: 600px) {
-  .container {
-    height: 35rem;
-    background: linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)),
+.container {
+  height: 30rem;
+  background:
+    linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)),
     linear-gradient(
       180deg,
       rgba(14, 45, 50, 0.04) 0%,
       rgba(14, 45, 50, 0.2) 100%
     ),
     linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)),
-    url("/images/eventAgenda/eventAgenda.jpg") no-repeat center 60%;
-    background-size: cover;
+    url('/images/components/agenda/Opentalent_Agenda_événement_culturel.jpg')
+      no-repeat center 60%;
+  background-size: cover;
+
+  @media (max-width: 600px) {
+    height: auto;
   }
 }
 
@@ -73,18 +78,37 @@ h3 {
   margin-top: 4rem;
   color: var(--on-primary-color);
   width: 45rem;
+
+  @media (max-width: 600px) {
+    font-size: 2rem;
+    margin-right: auto;
+    margin-left: auto;
+    max-width: 80%;
+  }
 }
 
 .btn-container {
-  display: flex;
-  align-items: center;
-  justify-content: center;
   padding: 0 20rem;
-}
 
-@media (max-width: 960px) {
-  .btn-container {
+  .v-col-12 {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  @media (max-width: 1240px) {
     padding: 0 5rem;
+    margin-top: 48px;
+
+    a {
+      display: block;
+      width: 80%;
+      margin: 5px auto;
+    }
+  }
+
+  @media (max-width: 1600px) {
+    padding: 0 5%;
   }
 }
 
@@ -99,5 +123,20 @@ h3 {
   min-width: 20rem;
   max-width: 20rem;
   height: 3.5rem;
+
+  @media (max-width: 1240px) {
+    width: 100%;
+    max-width: 100%;
+    margin: 0;
+    min-width: 0;
+  }
+}
+
+.btn-annuaire {
+  @media (max-width: 1240px) {
+    color: var(--on-primary-color);
+    font-weight: 600;
+    border: solid 2px var(--on-primary-color);
+  }
 }
 </style>

+ 37 - 29
components/Home/Help.vue

@@ -4,34 +4,28 @@ Section "Besoin d'aide" de la page d'accueil
 
 <template>
   <LayoutContainer>
-    <v-row >
+    <v-row class="center-90 mt-6">
       <v-col cols="12" lg="6" class="col">
-        <v-img src="/images/Home_logiciel/Opentalent_a_votre_service.png" />
+        <v-img
+          src="/images/pages/home/help/Opentalent_a_votre_service.png"
+          alt="Un homme et une femme tous les deux le sourire aux lèvres se serre la main"
+        />
       </v-col>
 
       <v-col cols="12" lg="6" class="col">
-        <h3>
-          Notre équipe est à vos côtés
-          pour vous guider
-        </h3>
+        <h3>Notre équipe est à vos côtés pour vous guider</h3>
 
         <p>
           Besoin d’aide ? <br />
-          Vous souhaitez en savoir plus sur nos solutions ou vous avez
-          besoin d'assistance sur l'utilisation de l'un de nos logiciels ?
+          Vous souhaitez en savoir plus sur nos solutions ou vous avez besoin
+          d'assistance sur l'utilisation de l'un de nos logiciels ?
         </p>
 
         <v-row>
           <ul>
-            <li>
-              Ouvert du lundi au vendredi de 8h15 à 17h45
-            </li>
-            <li>
-              Support joignable par mail
-            </li>
-            <li>
-              De nombreux articles tutoriels accessibles 24h/24
-            </li>
+            <li>Ouvert du lundi au vendredi de 8h30 à 17h30</li>
+            <li>Support joignable par mail</li>
+            <li>De nombreux articles tutoriels accessibles 24h/24</li>
           </ul>
         </v-row>
 
@@ -49,14 +43,9 @@ Section "Besoin d'aide" de la page d'accueil
   </LayoutContainer>
 </template>
 
-<script setup lang="ts">
-  import { useDisplay } from "vuetify";
-
-  const { mdAndDown} = useDisplay();
-</script>
+<script setup lang="ts"></script>
 
 <style scoped lang="scss">
-
 .v-container {
   margin: 64px auto 24px auto;
   padding: 16px;
@@ -76,6 +65,14 @@ Section "Besoin d'aide" de la page d'accueil
     padding: 60px;
     justify-content: center;
     align-items: self-start;
+
+    @media (max-width: 600px) {
+      padding: 12px;
+
+      * {
+        max-width: 100%;
+      }
+    }
   }
 }
 
@@ -126,9 +123,25 @@ ul {
   gap: 9px;
   margin-left: auto;
   margin-right: auto;
+
+  @media (max-width: 1240px) {
+    margin-top: 24px;
+    width: 40%;
+    margin-left: 30%;
+  }
+
+  @media (max-width: 600px) {
+    width: 90%;
+    margin-left: 5%;
+  }
 }
 
-@media (max-width: 960px) {
+@media (max-width: 1240px) {
+  .v-row {
+    width: 100%;
+    margin: 0;
+  }
+
   .v-img {
     width: 40rem;
     margin-left: auto;
@@ -159,10 +172,5 @@ ul {
     margin-right: auto;
     width: 30rem;
   }
-
-  .button-faq {
-    margin-left: 3rem;
-    margin-top: 2rem;
-  }
 }
 </style>

+ 129 - 66
components/Home/Promotion.vue

@@ -12,7 +12,8 @@
 
             <span class="inline-pic-container">
               <v-img
-                src="/images/Home_logiciel/ecole_de_musique-piano.jpg"
+                src="/images/pages/home/promotion/Visuel_d_un_Pianiste.png"
+                alt="Vignette d’une personne jouant sur un piano"
               />
             </span>
 
@@ -20,7 +21,8 @@
 
             <span class="inline-pic-container">
               <v-img
-                src="/images/Home_logiciel/ecole_de_danse-danseuse.jpg"
+                src="/images/pages/home/promotion/Visuel_de_Danseuse.png"
+                alt="Vignette d’une danseuse"
               />
             </span>
 
@@ -28,7 +30,8 @@
 
             <span class="inline-pic-container">
               <v-img
-                src="/images/Home_logiciel/ecole_de_cirque.jpg"
+                src="/images/pages/home/promotion/Visuel_d_un_Comedien.PNG"
+                alt="Vignette d’un homme faisant un spectacle de mime dans une salle de spectacle"
               />
             </span>
           </p>
@@ -39,75 +42,97 @@
     <v-row class="demo">
       <v-col>
         <v-img
-          src="/images/home/écran.JPG"
+          src="/images/pages/home/promotion/Ordinateur_portable_avec_ecran_logiciel_Opentalent.jpg"
+          alt="Vidéo corporate de l’entreprise Opentalent"
           class="screen"
         >
-          <v-icon icon="fas fa-play" class="play-icon" />
+          <v-icon v-show="false" icon="fas fa-play" class="play-icon" />
         </v-img>
-
       </v-col>
     </v-row>
 
-    <section class="outil">
-      <v-row>
-        <v-col>
-          <h3>
-            Un outil complet et intuitif <br />
-            pour chaque structure
-          </h3>
-        </v-col>
-      </v-row>
-
-      <v-row class="pictos">
-        <v-col cols="12" lg="6">
-          <v-row>
-            <img src="/images/pictoHome/network.svg" alt="network" />
-            <p>
-              Logiciel de gestion et communication en ligne
-            </p>
-          </v-row>
-
-          <v-row>
-            <img src="/images/pictoHome/website.svg" alt="website" />
-            <p>
-              Site web intégré et simple d’usage
-            </p>
-          </v-row>
-        </v-col>
-
-        <v-col cols="12" lg="6">
-          <v-row>
-            <img src="/images/pictoHome/visibility.svg" alt="visibility" />
-            <p>
-              Augmentez votre visibilité avec l'agenda culturel
-            </p>
-          </v-row>
-
-          <v-row>
-            <img src="/images/pictoHome/communication.svg" alt="communication" />
-            <p>
-              Communiquez en réseau
-            </p>
-          </v-row>
-        </v-col>
-      </v-row>
-    </section>
+    <v-row class="outil center-90">
+      <v-col>
+        <v-row>
+          <v-col>
+            <h3>Un outil complet et intuitif pour chaque structure</h3>
+          </v-col>
+        </v-row>
+
+        <v-row class="pictos">
+          <v-col cols="12" lg="6">
+            <v-row>
+              <v-col cols="3">
+                <img
+                  src="/images/pages/home/promotion/Logiciel_en_ligne_SaaS.svg"
+                  alt="Icône nuage cloud"
+                />
+              </v-col>
+              <v-col cols="9">
+                <p>Logiciel de gestion et communication en ligne</p>
+              </v-col>
+            </v-row>
+
+            <v-row>
+              <v-col cols="3">
+                <img
+                  src="/images/pages/home/promotion/Site_internet_intégré.svg"
+                  alt="Icône site internet"
+                />
+              </v-col>
+              <v-col cols="9">
+                <p>Site web intégré et simple d’usage</p>
+              </v-col>
+            </v-row>
+          </v-col>
+
+          <v-col cols="12" lg="6">
+            <v-row>
+              <v-col cols="3">
+                <img
+                  src="/images/pages/home/promotion/Visibilite_augmente_avec_l_agenda_culturel_Opentalent.svg"
+                  alt="Icône avion en papier"
+                />
+              </v-col>
+              <v-col cols="9">
+                <p>Augmentez votre visibilité avec l'agenda culturel</p>
+              </v-col>
+            </v-row>
+
+            <v-row>
+              <v-col cols="3">
+                <img
+                  src="/images/pages/home/promotion/Icone_communication_en_reseau.svg"
+                  alt="Icône de deux enveloppes"
+                />
+              </v-col>
+              <v-col cols="9">
+                <p>Communiquez en réseau</p>
+              </v-col>
+            </v-row>
+          </v-col>
+        </v-row>
+      </v-col>
+    </v-row>
   </LayoutContainer>
 </template>
 
-<script setup lang="ts">
-</script>
+<script setup lang="ts"></script>
 
 <style scoped lang="scss">
-
 .highlight {
   color: var(--secondary-color);
 }
 
 .v-row.gestion {
-  >.v-col {
+  > .v-col {
     margin-bottom: 4rem;
     background: var(--primary-color);
+
+    @media (max-width: 600px) {
+      min-height: 430px;
+      padding: 0 5%;
+    }
   }
 
   .text-block {
@@ -118,6 +143,10 @@
     height: 20rem;
     width: 45rem;
     margin: 2rem auto 28rem;
+
+    @media (max-width: 600px) {
+      padding: 0 5%;
+    }
   }
 
   .inline-pic-container {
@@ -127,20 +156,24 @@
   }
 
   .v-img {
-    height: auto;
-    width: 7rem;
+    height: 75px;
+    width: 115px;
     max-width: 100%;
     border-radius: 5rem;
   }
 
   @media (max-width: 960px) {
+    > .v-col {
+      margin-bottom: 0;
+    }
+
     .text-block {
       font-weight: 500;
       font-size: 2rem;
       line-height: 3.5rem;
       height: 10rem;
       width: 40rem;
-      margin: 3rem 2rem 5rem;
+      margin: 3rem auto 5rem;
     }
 
     .v-img {
@@ -151,7 +184,11 @@
 }
 
 .v-row.demo {
-  margin-bottom: -28rem;
+  max-height: 350px;
+
+  @media (max-width: 1280px) {
+    max-height: 1000px;
+  }
 
   .screen {
     width: 900px;
@@ -163,9 +200,12 @@
     bottom: 30rem;
   }
 
-  @media (max-width: 960px) {
+  @media (max-width: 1280px) {
     .screen {
+      margin-top: -12px;
+      bottom: 0;
       width: 100%;
+      border-radius: 0;
     }
   }
 
@@ -187,9 +227,15 @@
   }
 }
 
-section.outil {
+.outil {
   margin-bottom: 36px;
 
+  @media (max-width: 600px) {
+    width: 90%;
+    margin-left: auto;
+    margin-right: auto;
+  }
+
   h3 {
     color: var(--primary-color);
     font-size: 2rem;
@@ -200,31 +246,48 @@ section.outil {
 
   .pictos {
     .v-row {
-      border-bottom: solid 1px var(--on-primary-color-alt);
-      margin: 0;
+      border-bottom: solid 2px var(--on-neutral-color-extra-light);
+      border-top: solid 2px var(--on-neutral-color-extra-light);
+      margin: -2px 0 0;
       height: 100px;
       display: flex;
       align-items: center;
       justify-content: center;
     }
 
-    .v-row:first-child {
-      border-top: solid 1px var(--on-primary-color-alt);
+    > .v-col-12 {
+      padding-top: 0;
+      padding-bottom: 0;
+    }
+
+    .v-col-3 {
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-end;
     }
 
     img {
       width: 50px;
       height: 50px;
       margin-right: 2rem;
+
+      @media (max-width: 600px) {
+        margin-right: 0;
+      }
     }
 
     p {
       font-weight: 400;
-      font-size: 22px;
+      font-size: 20px;
       line-height: 26px;
       width: 25rem;
+      max-width: 100%;
       color: var(--primary-color);
-      margin-bottom: 1rem;
+
+      @media (max-width: 600px) {
+        width: 90%;
+        margin-bottom: 0;
+      }
     }
   }
 }

+ 78 - 74
components/Home/Reviews.vue

@@ -1,26 +1,19 @@
 <template>
   <LayoutContainer>
     <div class="container-1">
-      <LayoutUISectionTitle>
-        Avis Clients
-      </LayoutUISectionTitle>
+      <LayoutUISectionTitle> Avis Clients </LayoutUISectionTitle>
 
-      <h4>
-        C'est vous qui le dites
-      </h4>
+      <h4>C'est vous qui le dites</h4>
     </div>
 
     <!-- Ecrans larges -->
-    <div v-if="mdAndUp" class="container-2">
-
+    <div v-if="lgAndUp" class="container-2">
       <!-- Partie 1 : Avis clients -->
       <v-row justify="center">
         <div class="col-review">
           <v-col cols="6">
             <v-card class="left mx-auto">
-              <v-card-title>
-                Patrice CATHELIN
-              </v-card-title>
+              <v-card-title> Patrice CATHELIN </v-card-title>
 
               <v-card-text>
                 <p>
@@ -44,9 +37,7 @@
 
           <v-col cols="6">
             <v-card class="right mx-auto">
-              <v-card-title>
-                Karine GIRAUD
-              </v-card-title>
+              <v-card-title> Karine GIRAUD </v-card-title>
 
               <v-card-text>
                 <p>
@@ -60,9 +51,7 @@
               </v-card-text>
 
               <div class="card-footer">
-                <small class="status">
-                  Secrétaire administrative
-                </small>
+                <small class="status"> Secrétaire administrative </small>
 
                 <small class="structure">
                   Association Musicale Sainte Cécile de Lagord (17)
@@ -77,9 +66,7 @@
         <div class="col-review">
           <v-col cols="6">
             <v-card class="left mx-auto">
-              <v-card-title>
-                Laurent BEL
-              </v-card-title>
+              <v-card-title> Laurent BEL </v-card-title>
 
               <v-card-text>
                 <p>
@@ -106,9 +93,7 @@
 
           <v-col cols="6">
             <v-card class="right mx-auto">
-              <v-card-title>
-                Philippe BORY
-              </v-card-title>
+              <v-card-title> Philippe BORY </v-card-title>
 
               <v-card-text>
                 <p>
@@ -121,9 +106,7 @@
               </v-card-text>
 
               <div class="card-footer">
-                <small class="status">
-                  Personnel administratif
-                </small>
+                <small class="status"> Personnel administratif </small>
 
                 <small class="structure">
                   École d'Arts de Saint-Michel-sur-Orge (91)
@@ -134,7 +117,7 @@
         </div>
       </v-row>
 
-      <!-- Partie 1 : Carrousel logos clients -->
+      <!-- Partie 2 : Carrousel logos clients -->
       <div class="carousel-clients-container">
         <CommonCarouselClients :items="items" />
       </div>
@@ -144,7 +127,7 @@
     <div v-else class="container-sm">
       <v-row>
         <v-col cols="12">
-          <Carousel :itemsToShow="1" :wrapAround="true" ref="reviewCarousel">
+          <Carousel ref="reviewCarousel" :items-to-show="1" :wrap-around="true">
             <Slide v-for="(card, index) in cards" :key="index">
               <v-card>
                 <v-card-title>
@@ -168,12 +151,9 @@
         </v-col>
       </v-row>
 
-      <v-row class="justify-center align-center">
+      <v-row class="justify-center align-center mb-8">
         <v-col class="d-flex justify-space-around align-center">
-          <v-btn
-            icon="fas fa-arrow-left-long"
-            @click="goToPrevious"
-          />
+          <v-btn icon="fas fa-arrow-left-long" @click="goToPrevious" />
 
           <div class="carousel-controls">
             <div
@@ -184,89 +164,109 @@
             />
           </div>
 
-          <v-btn
-            icon="fas fa-arrow-right-long"
-            @click="goToNext"
-          />
+          <v-btn icon="fas fa-arrow-right-long" @click="goToNext" />
         </v-col>
       </v-row>
+
+      <CommonCarouselClients :items="items" class="alt-theme pt-12" />
     </div>
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-import { Carousel, Slide } from "vue3-carousel";
-import "vue3-carousel/dist/carousel.css";
-import { useDisplay } from "vuetify";
-import type { Review } from "~/types/interface";
+import { Carousel, Slide } from 'vue3-carousel'
+import 'vue3-carousel/dist/carousel.css'
+import { useDisplay } from 'vuetify'
+import type { Ref } from 'vue'
+import type { Review } from '~/types/interface'
 
-const { mdAndUp } = useDisplay();
+const { lgAndUp } = useDisplay()
 
-const reviewCarousel: Ref<typeof Carousel | null> = ref(null);
+const reviewCarousel: Ref<typeof Carousel | null> = ref(null)
 
 const state = ref({
   activeIndex: 0,
-});
+})
 
 const goToNext = () => {
-  reviewCarousel.value!.next();
-  state.value.activeIndex = (state.value.activeIndex + 1) % cards.length;
+  reviewCarousel.value!.next()
+  state.value.activeIndex = (state.value.activeIndex + 1) % cards.length
 }
 
 const goToPrevious = () => {
-  reviewCarousel.value!.prev();
+  reviewCarousel.value!.prev()
   state.value.activeIndex =
     state.value.activeIndex - 1 < 0
       ? cards.length - 1
-      : state.value.activeIndex - 1;
+      : state.value.activeIndex - 1
 }
 
 const cards: Array<Review> = [
   {
-    name: "Patrice CATHELIN",
+    name: 'Patrice CATHELIN',
     review:
       "C'est un logiciel très bien conçu et efficace avec une équipe ouverte, dynamique et à l'écoute. L’assistance est très réactive, j'ai toujours eu une réponse rapide à mes besoins, ce qui est fort appréciable.",
-    status: "Directeur administratif & pédagogique",
-    structure: "Conservatoire de Musique & de Danse de Sens (78)",
+    status: 'Directeur administratif & pédagogique',
+    structure: 'Conservatoire de Musique & de Danse de Sens (78)',
   },
   {
-    name: "Karine GIRAUD",
+    name: 'Karine GIRAUD',
     review:
       "Étant présente depuis presque le début, je suis fière d'avoir vu grandir ce logiciel et d'avoir évoluée avec lui. De plus, je me suis sentie écoutée lors de mes propositions d'amélioration, car beaucoup ont vu le jour. Enfin, l'accompagnement et la réactivité n'ont jamais faibli depuis toutes ces années",
-    status: "Secrétaire administrative",
-    structure: "Association Musicale Sainte Cécile de Lagord (17)",
+    status: 'Secrétaire administrative',
+    structure: 'Association Musicale Sainte Cécile de Lagord (17)',
   },
   {
-    name: "Laurent BEL",
+    name: 'Laurent BEL',
     review:
       "Logiciel très complet qui permet de faire beaucoup de choses. J’apprécie particulièrement la réactivité, la bienveillance et le fait que l’équipe soit à l'écoute pour faire évoluer l'outil en fonction de nos besoins. Si besoin, la FAQ est vraiment utile. Elle permet de trouver rapidement une solution face à un problème rencontré.",
-    status: "Directeur administratif & pédagogique",
-    structure: "École de Musique EPIC Musique en 4 Rivières (74)",
+    status: 'Directeur administratif & pédagogique',
+    structure: 'École de Musique EPIC Musique en 4 Rivières (74)',
   },
   {
-    name: "Philippe BORY",
+    name: 'Philippe BORY',
     review:
       "Opentalent est une entreprise avec de vraies valeurs humaines, à l'écoute de chaque structure et qui ne cesse de s'améliorer pour toujours coller aux besoins de ses clients. Plus qu'une relation commerciale, c'est pour nous un véritable partenaire au quotidien.",
-    status: "Personnel administratif",
+    status: 'Personnel administratif',
     structure: "École d'Arts de Saint-Michel-sur-Orge (91)",
   },
-];
-
-const items: Ref<Array<{ src: string }>> = ref([
-  { src: "/images/reviews/school/review1.svg" },
-  { src: "/images/reviews/school/review2.png" },
-  { src: "/images/reviews/school/review3.png" },
-  { src: "/images/reviews/school/review4.jpeg" },
-  { src: "/images/reviews/school/review5.jpeg" },
-  { src: "/images/reviews/school/review6.jpeg" },
-]);
+]
+
+const items: Ref<Array<{ src: string; alt: string }>> = ref([
+  {
+    src: '/images/pages/home/reviews/Logo_Conservatoire_Les_Ateliers_des_Arts_Agglomeration_du_Puy-en-Velay.svg',
+    alt: 'Logo du Conservatoire « Les ateliers des arts',
+  },
+  {
+    src: '/images/pages/home/reviews/Logo_Conservatoire-Senlis.png',
+    alt: 'Logo du Conservatoire de Senlis',
+  },
+  {
+    src: '/images/pages/home/reviews/Logo_Ecole_de_Musique-Sausheim.png',
+    alt: 'Logo de l’École de musique Sausheim',
+  },
+  {
+    src: '/images/pages/home/reviews/Logo_Conservatoire_Marly_le_Roi-Roger_Bourdin.jpeg',
+    alt: 'Logo du Conservatoire Marly le Roi Roger Bourdin',
+  },
+  {
+    src: '/images/pages/home/reviews/Logo_Conservatoire_de_Musiques_et_de_Danses_du_Thouarsais.jpeg',
+    alt: 'Logo du Conservatoire de Musique et de Danse du Thouarsais',
+  },
+  {
+    src: '/images/pages/home/reviews/Logo_Conservatoire_de_Musique_d_Annemasse.jpg',
+    alt: 'Logo du Conservatoire d’Annemasse',
+  },
+])
 </script>
 
 <style scoped>
-
 .container-1 {
-  background-color: var(--neutral-color);
-  height: 22rem;
+  background-color: var(--neutral-color-alt-light);
+
+  @media (min-width: 1240px) {
+    height: 22rem;
+  }
 
   h4 {
     font-size: 2rem;
@@ -282,7 +282,6 @@ const items: Ref<Array<{ src: string }>> = ref([
 
 .container-2 {
   background-color: var(--primary-color);
-  height: 60rem;
 
   .col-review {
     display: flex;
@@ -335,11 +334,15 @@ const items: Ref<Array<{ src: string }>> = ref([
           letter-spacing: 0.18em;
           text-transform: uppercase;
           margin-bottom: 2rem;
+          width: 300px;
+          right: 18px;
         }
 
         .structure {
           font-size: 0.8rem;
           margin-bottom: 1rem;
+          width: 300px;
+          right: 18px;
         }
       }
     }
@@ -362,11 +365,12 @@ const items: Ref<Array<{ src: string }>> = ref([
 
 .container-sm {
   .v-card {
-    width: 300px;
+    width: 70%;
     display: flex;
     flex-direction: column;
     justify-content: center;
     align-items: center;
+    padding: 16px;
   }
 
   .carousel-controls {

+ 156 - 100
components/Home/Solution.vue

@@ -4,31 +4,26 @@ Section "Solutions" de la page d'accueil
 
 <template>
   <LayoutContainer>
-    <LayoutUISectionTitle class="alt-theme">
-      3 solutions
-    </LayoutUISectionTitle>
+    <LayoutUISectionTitle class="alt-theme"> 3 solutions </LayoutUISectionTitle>
 
-    <h4 class="text-center" >
-      Trouvez la solution faites pour vous
-    </h4>
+    <h4 class="text-center mb-4">Trouvez la solution faite pour vous</h4>
 
     <v-row class="solutions center-90">
       <v-col
         v-for="(solution, index) in solutions"
         :key="index"
-        cols="4"
+        cols="12"
+        lg="4"
       >
         <v-container>
           <div class="d-flex justify-center align-left flex-column">
-            <small>
-              Opentalent
-            </small>
+            <small> Opentalent </small>
 
             <h2>
               {{ solution.name }}
             </h2>
 
-            <v-divider thickness="2"/>
+            <v-divider thickness="2" />
 
             <p>
               {{ solution.description }}
@@ -36,37 +31,36 @@ Section "Solutions" de la page d'accueil
 
             <nuxt-link :to="solution.link">
               <v-row>
-                <div :class="['image-container', solution.class]" >
+                <div :class="['image-container', solution.class]">
                   <v-img :src="solution.image" />
-                  <v-btn>Découvrir</v-btn>
+                  <v-btn v-if="xlAndUp">Découvrir</v-btn>
                 </div>
               </v-row>
             </nuxt-link>
 
-            <v-row>
-              <div class="details">
-                <v-col cols="6">
-                  <ul>
-                    <li
-                      v-for="(sol, i) in solution.solutions.slice(0, 4)"
-                      :key="i"
-                    >
-                      {{ sol }}
-                    </li>
-                  </ul>
-                </v-col>
-
-                <v-col cols="6">
-                  <ul>
-                    <li
-                      v-for="(sol, i) in solution.solutions.slice(4)"
-                      :key="i"
-                    >
-                      {{ sol }}
-                    </li>
-                  </ul>
-                </v-col>
-              </div>
+            <v-row class="details">
+              <v-col cols="12" sm="6">
+                <ul>
+                  <li
+                    v-for="(sol, i) in solution.solutions.slice(0, 4)"
+                    :key="i"
+                  >
+                    {{ sol }}
+                  </li>
+                </ul>
+              </v-col>
+
+              <v-col cols="12" sm="6">
+                <ul>
+                  <li v-for="(sol, i) in solution.solutions.slice(4)" :key="i">
+                    {{ sol }}
+                  </li>
+                </ul>
+              </v-col>
+            </v-row>
+
+            <v-row v-if="lgAndDown">
+              <v-btn :to="solution.link">Découvrir</v-btn>
             </v-row>
           </div>
         </v-container>
@@ -74,7 +68,7 @@ Section "Solutions" de la page d'accueil
     </v-row>
 
     <v-container class="footer">
-      <v-row >
+      <v-row>
         <v-col cols="12">
           <p>* en option</p>
         </v-col>
@@ -84,70 +78,78 @@ Section "Solutions" de la page d'accueil
 </template>
 
 <script setup lang="ts">
+import { useDisplay } from 'vuetify'
+import type { SolutionItem } from '~/types/interface'
 
-import type { SolutionItem } from "~/types/interface";
+const { xlAndUp, lgAndDown } = useDisplay()
 
 const solutions: Array<SolutionItem> = [
   {
-    name: "Artist",
-    description: "Orchestres, chorales, compagnies de danse, théâtre et cirque",
-    image: "/images/logo/logiciels/Artist-Blanc.png",
-    link: "/opentalent_artist",
-    class: "artist-image",
+    name: 'Artist',
+    description: 'Orchestres, chorales, compagnies et troupes artistiques',
+    image: '/images/logos/Logo_Opentalent_Artist-blanc.png',
+    alt: 'Partition tenue par une femme dans une chorale',
+    link: '/opentalent_artist',
+    class: 'artist-image',
     solutions: [
-      "Gestion des membres",
-      "Agenda de la structure",
-      "Matériel & médiathèque",
-      "Export de données",
-      "Communication",
-      "Statistiques",
-      "Site internet intégré",
-      "Partage de données en réseau",
+      'Gestion des membres',
+      'Agenda de la structure',
+      'Matériel & médiathèque',
+      'Export de données',
+      'Communication',
+      'Statistiques',
+      'Site internet intégré',
+      'Partage de données en réseau',
     ],
   },
   {
-    name: "School",
+    name: 'School',
     description: "Petits et grands établissements d'enseignement artistique",
-    image: "/images/logo/logiciels/School-Blanc.png",
-    link: "/opentalent_school",
-    class: "school-image",
+    image: '/images/logos/Logo_Opentalent_School-blanc',
+    alt: 'Deux jeunes filles jouant du violon',
+    link: '/opentalent_school',
+    class: 'school-image',
     solutions: [
-      "Gestion des membres",
-      "Préinscription en ligne*",
-      "Agenda de la structure",
-      "Suivi pédagogique",
-      "Gestion administrative et financière",
-      "Communication",
-      "Site internet intégré",
-      "Statistiques",
-    ]
+      'Gestion des membres',
+      'Préinscription en ligne *',
+      'Agenda de la structure',
+      'Suivi pédagogique',
+      'Gestion administrative et financière',
+      'Communication',
+      'Site internet intégré',
+      'Statistiques',
+    ],
   },
   {
-    name: "Manager",
-    description: "Fédérations, confédérations et collectivités",
-    image: "/images/logo/logiciels/Manager-Blanc.png",
-    link: "/opentalent_manager",
-    class: "manager-image",
+    name: 'Manager',
+    description: 'Fédérations, confédérations et collectivités',
+    image: '/images/logos/Logo_Opentalent_Manager-blanc.png',
+    alt: 'Carte de réseau des structures de la confédération musicale de France',
+    link: '/opentalent_manager',
+    class: 'manager-image',
     solutions: [
-      "Gestion des membres",
-      "Agenda du réseau",
-      "Matériel & médiathèque",
-      "Gestion administrative",
-      "Statistiques du réseau",
-      "Cotisations",
-      "Site internet intégré",
-      "Communication",
+      'Gestion des membres',
+      'Agenda du réseau',
+      'Matériel & médiathèque',
+      'Gestion administrative',
+      'Statistiques du réseau',
+      'Cotisations',
+      'Site internet intégré',
+      'Communication',
     ],
   },
-];
+]
 </script>
 
 <style scoped lang="scss">
 .container {
   background: var(--primary-color);
-  margin-bottom: 15rem;
-  height: 36rem;
   position: relative;
+
+  @media (max-width: 1240px) {
+    height: 100%;
+    margin-bottom: 0;
+  }
 }
 
 h4 {
@@ -157,16 +159,25 @@ h4 {
   text-align: center;
   color: var(--on-primary-color);
   width: 100%;
+
+  @media (max-width: 1240px) {
+    width: 90%;
+    margin-left: auto;
+    margin-right: auto;
+  }
+
+  @media (max-width: 600px) {
+    font-size: 1.6rem;
+  }
 }
 
 @media (min-width: 600px) {
   h3 {
-    margin-bottom: 3rem
+    margin-bottom: 3rem;
   }
 }
 
 .v-row.solutions {
-
   small {
     font-weight: 600;
     font-size: 10px;
@@ -186,7 +197,7 @@ h4 {
 
   .v-divider {
     color: var(--on-primary-color-alt);
-    width: 20rem;
+    width: 350px;
     opacity: 0.7;
   }
 
@@ -216,10 +227,16 @@ h4 {
       right: 0;
       width: 200px;
     }
+
+    @media (max-width: 1240px) {
+      display: flex;
+      flex-direction: column;
+      width: 100%;
+    }
   }
 
   .image-container::before {
-    content: "";
+    content: '';
     position: absolute;
     top: 0;
     left: 0;
@@ -232,16 +249,25 @@ h4 {
   }
 
   .v-btn {
-    position: absolute;
-    z-index: 100;
-    bottom: 40%;
     left: 50%;
-    transform: translateX(-50%);
-    display: none;
     font-size: 0.8rem;
     border-radius: 6px;
     background: var(--secondary-color);
-    color: var(--on-primary-color);
+    color: var(--on-secondary-color);
+
+    @media (min-width: 1240px) {
+      position: absolute;
+      z-index: 100;
+      bottom: 40%;
+      transform: translateX(-50%);
+      display: none;
+    }
+
+    @media (max-width: 1240px) {
+      left: auto;
+      width: 90%;
+      margin: 24px auto;
+    }
   }
 
   .image-container:hover .v-btn {
@@ -249,7 +275,7 @@ h4 {
   }
 
   .artist-image {
-    background-image: url(/images/solutions/artist.jpg);
+    background-image: url(/images/pages/home/solution/Opentalent_Artist_pour_les_structures_culturelles.jpg);
   }
 
   .artist-image:hover::before {
@@ -258,7 +284,7 @@ h4 {
   }
 
   .school-image {
-    background-image: url(/images/solutions/school.jpg);
+    background-image: url(/images/pages/home/solution/Opentalent_School_pour_les_etablissements_d_enseignement_artistique.jpg);
   }
 
   .school-image:hover::before {
@@ -267,7 +293,7 @@ h4 {
   }
 
   .manager-image {
-    background-image: url(/images/solutions/manager.png);
+    background-image: url(/images/pages/home/solution/Opentalent_Manager_pour_les_reseaux_culturels.png);
   }
 
   .manager-image:hover::before {
@@ -279,18 +305,42 @@ h4 {
     display: flex;
     justify-content: center;
     align-items: center;
+    max-width: 80%;
 
     ul {
       margin-top: 0.9rem;
-      font-size: 0.5rem;
+      max-width: 100%;
+      white-space: pre-wrap;
+      margin-left: 1rem;
     }
 
     li {
-      font-size: 0.8rem;
-      width: 10rem;
-      margin-left: 1rem;
+      text-align: start;
+      font-size: 16px;
       line-height: 18px;
-      color: var(--primary-color);
+      color: var(--on-primary-color);
+      margin: 6px 0;
+
+      @media (max-width: 1240px) {
+        font-size: 1.1rem;
+      }
+    }
+
+    @media (max-width: 1240px) {
+      margin: 0 auto;
+    }
+
+    @media (max-width: 600px) {
+      padding: 18px;
+
+      ul {
+        margin-top: 0;
+      }
+
+      .v-col-12 {
+        padding-top: 0;
+        padding-bottom: 0;
+      }
     }
   }
 }
@@ -298,7 +348,13 @@ h4 {
 .footer {
   p {
     text-align: right;
-    font-size: 12px;
+    font-size: 14px;
+    color: var(--on-primary-color);
+
+    @media (max-width: 1240px) {
+      font-size: 1.1rem;
+      color: var(--on-primary-color);
+    }
   }
 }
 </style>

+ 60 - 60
components/JoinUs/Form.vue

@@ -1,20 +1,12 @@
 <template>
   <div>
-    <v-card
-      v-if="!jobApplicationSent"
-    >
-      <v-card-title
-        class="text-center"
-      >
+    <v-card v-if="!jobApplicationSent">
+      <v-card-title class="text-center">
         Formulaire de Candidature
       </v-card-title>
 
       <v-card-text>
-        <v-form
-          ref="form"
-          validate-on="submit lazy"
-          @submit.prevent="submit"
-        >
+        <v-form ref="form" validate-on="submit lazy" @submit.prevent="submit">
           <v-text-field
             id="jobApplicationName"
             v-model="jobApplication.name"
@@ -45,7 +37,6 @@
             :rules="[validateEmail]"
             label="Email*"
             required
-
           />
 
           <v-file-input
@@ -74,46 +65,43 @@
             label="Message*"
             required
           />
-          <span class="remaining-cars-notice">{{ leftCars }} caractères restants</span>
+          <span class="remaining-cars-notice"
+            >{{ leftCars }} caractères restants</span
+          >
 
           <div class="d-flex flex-column align-center mt-4">
             <!-- @see https://github.com/hCaptcha/vue-hcaptcha -->
-            <LayoutCaptcha/>
+            <LayoutCaptcha />
           </div>
         </v-form>
       </v-card-text>
 
-      <p class="text-right mr-6">
-        * Champs obligatoires
-      </p>
+      <p class="text-right mr-6">* Champs obligatoires</p>
 
       <v-card-actions class="justify-center">
-        <v-btn
-          class="btn-more mb-4 submit"
-          @click="submit"
-        >
-          Envoyer
-        </v-btn>
+        <v-btn class="btn-more mb-4 submit" @click="submit"> Envoyer </v-btn>
       </v-card-actions>
     </v-card>
   </div>
 </template>
 
 <script setup lang="ts">
-import ContactRequest from "~/models/Maestro/ContactRequest";
-import { useEntityManager } from "~/composables/data/useEntityManager";
-import JobApplication from "~/models/Maestro/JobApplication";
-import FileUtils from "~/services/utils/FileUtils";
+import type { ComputedRef, Ref } from 'vue'
+import { reactive } from 'vue'
+import ContactRequest from '~/models/Maestro/ContactRequest'
+import { useEntityManager } from '~/composables/data/useEntityManager'
+import JobApplication from '~/models/Maestro/JobApplication'
+import FileUtils from '~/services/utils/FileUtils'
 
 const { em } = useEntityManager()
 
-const form: Ref<any | null> = ref(null)
+const form: Ref<HTMLElement | null> = ref(null)
 
 const jobApplicationSent: Ref<boolean> = ref(false)
 
 const emit = defineEmits(['submit'])
 
-//@ts-ignore
+// @ts-ignore
 const jobApplication: ContactRequest = reactive(em.newInstance(JobApplication))
 
 const resumeUpload = ref(null)
@@ -123,40 +111,44 @@ const motivationLetterUpload = ref(null)
 // --- Validation ---
 const maxMessageLength = 2000
 
-const leftCars: ComputedRef<number> = computed(() =>
-  maxMessageLength - (jobApplication.message ? jobApplication.message.length : 0)
+const leftCars: ComputedRef<number> = computed(
+  () =>
+    maxMessageLength -
+    (jobApplication.message ? jobApplication.message.length : 0)
 )
 
 // Taille maximum en Mo
 const maxFileSize = 5
 
-const validateName = (name: string | null) => !!name || "Le nom est obligatoire";
+const validateName = (name: string | null) => !!name || 'Le nom est obligatoire'
 
-const validateSurname = (surname: string | null) => !!surname || "Le prénom est obligatoire";
+const validateSurname = (surname: string | null) =>
+  !!surname || 'Le prénom est obligatoire'
 
 const validateEmail = (email: string | null) =>
-  (!!email && /.+@.+\..+/.test(email)) || "L'adresse e-mail doit être valide";
+  (!!email && /.+@.+\..+/.test(email)) || "L'adresse e-mail doit être valide"
 
 const validatePhone = (email: string | null) =>
-  (!!email && /^((\+|00)33\s?|0)[1-7]([\s.]?\d{2}){4}$/.test(email)) || "Le numéro de téléphone doit être valide";
+  (!!email && /^((\+|00)33\s?|0)[1-7]([\s.]?\d{2}){4}$/.test(email)) ||
+  'Le numéro de téléphone doit être valide'
 
 const validateResume = () =>
-  resumeUpload.value !== null && resumeUpload.value[0] !== null || "Vous devez joindre un CV à l'un des formats indiqués";
+  (resumeUpload.value !== null && resumeUpload.value[0] !== null) ||
+  "Vous devez joindre un CV à l'un des formats indiqués"
 
 const validateFileSize = () =>
-  resumeUpload.value !== null
-  && resumeUpload.value[0] !== null
-  //@ts-ignore
-  && resumeUpload.value[0].size < (maxFileSize * 1024 * 1024)
-  || "La taille du fichier ne doit pas dépasser " + maxFileSize + " Mo";
+  (resumeUpload.value !== null &&
+    resumeUpload.value[0] !== null &&
+    // @ts-ignore
+    resumeUpload.value[0].size < maxFileSize * 1024 * 1024) ||
+  'La taille du fichier ne doit pas dépasser ' + maxFileSize + ' Mo'
 
 const validateNonEmptyMessage = (message: string | null) =>
-  (!!message && message.length > 0) ||
-  "Le message ne peut pas être vide";
+  (!!message && message.length > 0) || 'Le message ne peut pas être vide'
 
-const validateMessageLength = async (message: string | null) =>
+const validateMessageLength = (message: string | null) =>
   (!!message && message.length <= maxMessageLength) ||
-  "Le message ne doit pas dépasser " + maxMessageLength + " caractères";
+  'Le message ne doit pas dépasser ' + maxMessageLength + ' caractères'
 
 /**
  * Soumet le formulaire de candidature (boite de dialogue)
@@ -169,26 +161,33 @@ const submit = async () => {
     return
   }
 
-  jobApplication.resume = (resumeUpload.value !== null && resumeUpload.value[0] !== null) ?
-    {
-      //@ts-ignore
-      'name': resumeUpload.value[0].name,
-      'content': await FileUtils.blobToBase64(resumeUpload.value[0])
-    } : null
-
-  jobApplication.motivationLetter = (motivationLetterUpload.value !== null && motivationLetterUpload.value[0] !== null) ?
-    {
-      //@ts-ignore
-      'name': motivationLetterUpload.value[0].name,
-      'content': await FileUtils.blobToBase64(motivationLetterUpload.value[0])
-    } : null
+  jobApplication.resume =
+    resumeUpload.value !== null && resumeUpload.value[0] !== null
+      ? {
+          // @ts-ignore
+          name: resumeUpload.value[0].name,
+          content: await FileUtils.blobToBase64(resumeUpload.value[0]),
+        }
+      : null
+
+  jobApplication.motivationLetter =
+    motivationLetterUpload.value !== null &&
+    motivationLetterUpload.value[0] !== null
+      ? {
+          // @ts-ignore
+          name: motivationLetterUpload.value[0].name,
+          content: await FileUtils.blobToBase64(
+            motivationLetterUpload.value[0]
+          ),
+        }
+      : null
 
   await em.persist(JobApplication, jobApplication)
 
-  jobApplicationSent.value = true;
+  jobApplicationSent.value = true
 
   emit('submit')
-};
+}
 </script>
 
 <style scoped lang="scss">
@@ -196,6 +195,7 @@ const submit = async () => {
   width: 100%;
   margin-bottom: 0 !important;
   height: 55px;
+  background: var(--secondary-color);
 }
 
 .submit:hover {

+ 51 - 45
components/JoinUs/MissionDetail.vue

@@ -1,7 +1,7 @@
 <template>
   <LayoutContainer>
     <div class="job-section">
-      <v-row class="mb-6">
+      <v-row class="mb-6 center-90">
         <v-col class="d-flex align-items-center">
           <v-btn
             to="/nous-rejoindre"
@@ -17,25 +17,19 @@
       <div>
         <div v-if="pending">
           <v-row class="justify-center progress">
-            <v-progress-circular
-              indeterminate
-              color="grey"
-            />
+            <v-progress-circular indeterminate color="grey" />
           </v-row>
         </div>
 
         <div v-else-if="job !== null">
-          <CommonMeta
-            :title="job.title"
-            description="Offre d'emploi"
-          />
+          <CommonMeta :title="job.title" description="Offre d'emploi" />
 
-          <LayoutUITitlePage>
+          <h3>
             {{ job.title }}
-          </LayoutUITitlePage>
+          </h3>
 
           <v-row class="details blue-content my-6">
-            <v-col cols="6">
+            <v-col cols="12" md="6">
               <v-row>
                 <div>
                   Type de contrat :
@@ -45,13 +39,13 @@
 
               <v-row>
                 <div>
-                  Location :
+                  Localisation :
                   <b>{{ job.postalCode }} {{ job.city }}</b>
                 </div>
               </v-row>
             </v-col>
 
-            <v-col cols="6">
+            <v-col cols="12" md="6">
               <v-row>
                 <div>
                   Secteur d'activité : <b>{{ job.sector.join(', ') }}</b>
@@ -67,54 +61,50 @@
             </v-col>
           </v-row>
 
-          <v-row>
-            <p
-              v-html="job.content"
-              class="center-90 description mb-12"
-            />
+          <v-row class="center-90">
+            <p class="center-90 description mb-12" v-html="job.content" />
           </v-row>
 
           <v-row class="d-flex justify-center align-center">
-            <v-btn
-              prepend-icon="fas fa-info"
-              class="btn-apply mb-12"
-            >
-              Je postule
-            </v-btn>
+            <v-btn class="btn-apply mb-12"> Je postule </v-btn>
           </v-row>
 
           <v-row class="d-flex justify-space-between center-90">
-            <p>
-              MOTS CLÉS
-            </p>
-            <div>
+            <p>MOTS CLÉS</p>
+            <div v-if="mdAndUp">
               <p>PARTAGER</p>
             </div>
           </v-row>
 
           <v-row class="d-flex justify-space-between mb-8 center-90">
             <p class="key-word mt-3">
-              <span v-for="tag in job.tags" class="mr-2">
+              <span v-for="tag in job.tags" :key="tag.id" class="mr-2">
                 {{ tag.name }}
               </span>
             </p>
+            <CommonShare v-if="mdAndUp" />
+          </v-row>
 
+          <div v-if="smAndDown">
+            <p>PARTAGER</p>
             <CommonShare />
-          </v-row>
+          </div>
         </div>
       </div>
     </div>
-
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-import "vue3-carousel/dist/carousel.css";
-import { useEntityFetch } from "~/composables/data/useEntityFetch";
-import JobPosting from "~/models/Maestro/JobPosting";
-import DateUtils from "~/services/utils/dateUtils";
+import 'vue3-carousel/dist/carousel.css'
+import { useDisplay } from 'vuetify'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import JobPosting from '~/models/Maestro/JobPosting'
+import DateUtils from '~/services/utils/dateUtils'
+
+const { mdAndUp, smAndDown } = useDisplay()
 
-const route = useRoute();
+const route = useRoute()
 const { fetch } = useEntityFetch()
 
 const jobId: number = parseInt(route.params.id as string)
@@ -127,10 +117,10 @@ const { data: job, pending } = fetch(JobPosting, jobId)
 const formatDate = (date: string) => {
   console.log(date)
   if (!date) {
-    return "-"
+    return '-'
   }
-  return DateUtils.format(new Date(date), "dd/MM/yyyy")
-};
+  return DateUtils.format(new Date(date), 'dd/MM/yyyy')
+}
 </script>
 
 <style scoped lang="scss">
@@ -139,13 +129,25 @@ const formatDate = (date: string) => {
 }
 
 .job-section {
-  margin: 32px 12%;
+  margin: 32px 0;
+
+  h3 {
+    font-size: 32px;
+    width: 100%;
+    text-align: center;
+    text-transform: uppercase;
+  }
 
   .details {
+    padding: 0 20%;
     background-color: var(--secondary-color);
     color: var(--on-secondary-color);
     height: 10rem;
 
+    @media (max-width: 600px) {
+      height: auto;
+    }
+
     .v-row {
       width: 90%;
       margin-left: auto;
@@ -157,15 +159,19 @@ const formatDate = (date: string) => {
       font-weight: 500;
       font-size: 25px;
       line-height: 18px;
+
+      @media (max-width: 600px) {
+        font-size: 16px;
+      }
     }
   }
 
   .description {
-    color: var(--primary-color);
-    text-align: justify;
-    font-size: 1.875rem;
+    color: var(--on-neutral-color);
+    font-size: 21px;
     font-weight: 500;
     line-height: 2.125rem;
+    padding: 12px 36px;
   }
 }
 
@@ -177,7 +183,7 @@ const formatDate = (date: string) => {
 
 .btn-apply {
   background: var(--secondary-color);
-  color: var(--neutral-color);
+  color: var(--on-secondary-color);
   display: flex;
   left: 0;
   padding: 25px 28px;

+ 72 - 56
components/JoinUs/Missions.vue

@@ -2,46 +2,34 @@
   <LayoutContainer>
     <div v-if="pending">
       <v-row class="justify-center progress">
-        <v-progress-circular
-          indeterminate
-          color="grey"
-        />
+        <v-progress-circular indeterminate color="grey" />
       </v-row>
     </div>
 
     <div
-      v-else
       v-for="(job, index) in jobs"
+      v-else
       :key="index"
       class="mission-container"
     >
-      <v-row class="title-container">
-        <NuxtLink
-          :to="`/nous-rejoindre/${job.id}`"
-          class="title"
-        >
+      <div class="title-container">
+        <NuxtLink :to="`/nous-rejoindre/${job.id}`" class="title">
           {{ job.title }} - {{ job.contractType }}
 
-          <v-icon
-            v-if="job.featured"
-            class="star fas fa-star"
-          />
+          <v-icon v-if="job.featured" class="star fas fa-star" />
         </NuxtLink>
 
-        <v-btn
-          :to="`/nous-rejoindre/${job.id}`"
-          class="btn-more"
-        >
+        <v-btn :to="`/nous-rejoindre/${job.id}`" class="btn-more">
           En savoir plus
         </v-btn>
-      </v-row>
+      </div>
 
-      <v-row class="location-container">
+      <div class="location-container">
         <v-icon icon="fas fa-map-marker" />
         <div class="location">
           {{ job.city }}
         </div>
-      </v-row>
+      </div>
     </div>
 
     <v-row>
@@ -50,27 +38,24 @@
           v-if="jobCollection && jobCollection.pagination"
           :model-value="page"
           :pagination="jobCollection.pagination"
-          @update:model-value="onPageUpdated"
           class="mt-4"
+          @update:model-value="onPageUpdated"
         />
       </v-col>
     </v-row>
 
-    <v-row class="ml-6 mb-6">
+    <v-row class="mb-6">
       <v-col cols="12">
         <p class="apply-now">
-          Nous sommes toujours à la recherche de nouveaux talents. N'hésitez pas
-          à déposer votre candidature ci-dessous :
+          Nous sommes toujours à la recherche de nouveaux talents.<br />
+          N'hésitez pas à déposer votre candidature ci-dessous :
         </p>
       </v-col>
     </v-row>
 
     <v-row>
       <v-col cols="12">
-        <v-btn
-          class="btn-send"
-          @click="dialog = true"
-        >
+        <v-btn class="btn-send" @click="dialog = true">
           Envoyer ma candidature
         </v-btn>
       </v-col>
@@ -85,51 +70,47 @@
       :retain-focus="false"
     >
       <div v-if="!jobApplicationSent">
-        <JoinUsForm @submit="onFormSubmit"/>
+        <JoinUsForm @submit="onFormSubmit" />
 
-        <v-btn @click="dialog = false">
-          Annuler
-        </v-btn>
+        <v-btn @click="dialog = false"> Annuler </v-btn>
       </div>
       <div v-else>
         <v-card class="pa-6 text-center">
-          Votre candidature a bien été envoyée, merci de votre intérêt.<br/>
+          Votre candidature a bien été envoyée, merci de votre intérêt.<br />
           Nous vous recontacterons dès que possible.
         </v-card>
 
-        <v-btn @click="dialog = false">
-          Fermer
-        </v-btn>
+        <v-btn @click="dialog = false"> Fermer </v-btn>
       </div>
     </v-dialog>
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-import { useEntityFetch } from "~/composables/data/useEntityFetch";
-import JobPosting from "~/models/Maestro/JobPosting";
-import type { AnyJson } from "~/types/data";
+import type { ComputedRef, Ref } from 'vue'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import JobPosting from '~/models/Maestro/JobPosting'
+import type { AnyJson } from '~/types/data'
 
 const { fetchCollection } = useEntityFetch()
 
-const page: Ref<number> = ref(1);
+const page: Ref<number> = ref(1)
 
 const query: ComputedRef<AnyJson> = computed(() => {
-    return { type: "ENTREPRISE", page: page.value }
-  }
-)
+  return { type: 'ENTREPRISE', page: page.value }
+})
 
-const { data: jobCollection, pending, refresh } = fetchCollection(
-  JobPosting,
-  null,
-  query
-)
+const {
+  data: jobCollection,
+  pending,
+  refresh,
+} = fetchCollection(JobPosting, null, query)
 
 // TODO: voir pourquoi on se retrouve obligé de passer par ce computed pour avoir le type TS correct?
 const jobs: ComputedRef<JobPosting[]> = computed(() => {
-  return jobCollection.value !== null ?
-         jobCollection.value.items as JobPosting[] :
-         []
+  return jobCollection.value !== null
+    ? (jobCollection.value.items as JobPosting[])
+    : []
 })
 
 const onPageUpdated = async (newVal: number): Promise<void> => {
@@ -148,7 +129,7 @@ const onPageUpdated = async (newVal: number): Promise<void> => {
 /**
  * Faut-il afficher la boite de dialogue de candidature
  */
-const dialog = ref(false);
+const dialog = ref(false)
 const jobApplicationSent: Ref<boolean> = ref(false)
 
 const onFormSubmit = () => {
@@ -164,12 +145,15 @@ const onFormSubmit = () => {
 .v-btn {
   font-weight: 600;
   height: 50px;
-  background: var(--secondary-color);
   border-radius: 6px;
-  color: var(--on-secondary-color);
+  color: var(--on-neutral-color);
   gap: 9px;
 }
 
+.v-btn:hover {
+  background-color: var(--on-neutral-color-extra-light);
+}
+
 .mission-container {
   margin: 64px 12%;
 
@@ -182,6 +166,11 @@ const onFormSubmit = () => {
     height: 80px;
     padding: 10px 10px 10px 1px;
 
+    @media (max-width: 600px) {
+      flex-direction: column;
+      height: auto;
+    }
+
     .title {
       font-weight: 600;
       font-size: 1.5rem;
@@ -189,6 +178,13 @@ const onFormSubmit = () => {
       color: var(--on-primary-color);
       text-decoration: none;
       margin-left: 36px;
+
+      @media (max-width: 600px) {
+        font-size: 1.2rem;
+        margin-left: auto;
+        margin-right: auto;
+        width: 90%;
+      }
     }
 
     .star {
@@ -202,6 +198,10 @@ const onFormSubmit = () => {
       margin-right: 8px;
       display: flex;
       align-items: center;
+
+      @media (max-width: 600px) {
+        margin: 12px auto;
+      }
     }
   }
 
@@ -221,6 +221,10 @@ const onFormSubmit = () => {
       margin-left: 10px;
       font-size: 1.3rem;
     }
+
+    @media (max-width: 600px) {
+      margin: 0 auto 12px auto;
+    }
   }
 }
 
@@ -238,16 +242,28 @@ const onFormSubmit = () => {
   margin-left: auto;
   margin-right: auto;
   font-weight: 700;
+  background-color: var(--secondary-color);
+
+  @media (max-width: 600px) {
+    width: 80%;
+    margin: 12px auto;
+  }
 }
 
 .apply-now {
   text-align: center;
   font-style: italic;
   font-weight: 300;
-  font-size: 34px;
+  font-size: 1.5rem;
   line-height: 40px;
   color: var(--primary-color);
   margin-bottom: 2rem;
+  margin-left: 24px;
+
+  @media (max-width: 600px) {
+    max-width: 90%;
+    margin: 12px auto;
+  }
 }
 
 .v-dialog {

+ 33 - 37
components/Layout/AnchoredSection.vue

@@ -1,55 +1,51 @@
 <template>
-  <div
-    :id="id"
-    ref="section"
-    v-scroll="onScroll"
-  >
-    <slot/>
+  <div :id="id" ref="section" v-scroll="onScroll">
+    <slot />
   </div>
 </template>
 
 <script setup lang="ts">
-  import { useLayoutStore } from "~/stores/layoutStore";
+import type { Ref } from 'vue'
+import { useLayoutStore } from '~/stores/layoutStore'
 
-  const layoutStore = useLayoutStore()
+const layoutStore = useLayoutStore()
 
-  const props = defineProps({
-    id: {
-      type: String,
-      required: true
-    }
-  })
+const props = defineProps({
+  id: {
+    type: String,
+    required: true,
+  },
+})
 
-  if (!props.id) {
-    throw new Error("Anchor's id is missing")
-  }
+if (!props.id) {
+  throw new Error("Anchor's id is missing")
+}
 
-  const section: Ref<HTMLElement | null> = ref(null)
+const section: Ref<HTMLElement | null> = ref(null)
 
-  layoutStore.setIsAnchoredSectionOnScreen(props.id, false)
+layoutStore.setIsAnchoredSectionOnScreen(props.id, false)
 
-  const top: Ref<number | null> = ref(null)
-  const bottom: Ref<number | null> = ref(null)
+const top: Ref<number | null> = ref(null)
+const bottom: Ref<number | null> = ref(null)
 
-  const onScroll = (scroll: any) => {
-    top.value = section.value!.offsetTop
-    bottom.value = section.value!.offsetTop + section.value!.offsetHeight
+// @ts-ignore
+const onScroll = (scroll) => {
+  top.value = section.value!.offsetTop
+  bottom.value = section.value!.offsetTop + section.value!.offsetHeight
 
-    if (top.value === null || bottom.value === null) {
-      return
-    }
+  if (top.value === null || bottom.value === null) {
+    return
+  }
 
-    const screenVerticalCenter = scroll.target.documentElement.scrollTop + window.innerHeight / 2
+  const screenVerticalCenter =
+    scroll.target.documentElement.scrollTop + window.innerHeight / 2
 
-    const active = screenVerticalCenter > top.value && screenVerticalCenter < bottom.value
-    if (active !== layoutStore.isAnchoredSectionOnScreen[props.id]) {
-        layoutStore.setIsAnchoredSectionOnScreen(
-          props.id,
-          active
-        )
-    }
+  const active =
+    screenVerticalCenter > top.value && screenVerticalCenter < bottom.value
+  if (active !== layoutStore.isAnchoredSectionOnScreen[props.id]) {
+    layoutStore.setIsAnchoredSectionOnScreen(props.id, active)
   }
+}
 </script>
 
-<style scoped>
-</style>
+<style scoped></style>

+ 39 - 36
components/Layout/Captcha.vue

@@ -1,29 +1,32 @@
 <template>
-  <vue-hcaptcha
-    :sitekey="siteKey"
-    @verify="onVerify"
-    @expired="onExpire"
-    @challenge-expired="onChallengeExpire"
-    @error="onError"
-  />
-  <v-checkbox
-    v-model="honeyPotChecked"
-    :rules="[validateCaptchaState]"
-    class="hidden-ctrl"
-  />
+  <div class="d-flex flex-column">
+    <vue-hcaptcha
+      :sitekey="siteKey"
+      @verify="onVerify"
+      @expired="onExpire"
+      @challenge-expired="onChallengeExpire"
+      @error="onError"
+    />
+    <v-checkbox
+      v-model="honeyPotChecked"
+      :rules="[validateCaptchaState]"
+      class="hidden-ctrl"
+    />
+  </div>
 </template>
 
 <script setup lang="ts">
-import VueHcaptcha from "@hcaptcha/vue3-hcaptcha";
+import VueHcaptcha from '@hcaptcha/vue3-hcaptcha'
+import type { Ref } from 'vue'
 
 const runtimeConfig = useRuntimeConfig()
 const siteKey = runtimeConfig.public.hCaptchaSiteKey
 
-const verified: Ref<boolean> = ref(false);
-const expired: Ref<boolean> = ref(false);
-const token: Ref<string> = ref("");
-const eKey: Ref<string> = ref("");
-const error: Ref<string> = ref("");
+const verified: Ref<boolean> = ref(false)
+const expired: Ref<boolean> = ref(false)
+const token: Ref<string> = ref('')
+const eKey: Ref<string> = ref('')
+const error: Ref<string> = ref('')
 
 // La case étant masquée, si elle est cochée, alors on peut en déduire
 // qu'on a affaire un robot (voir mécanisme du honey pot)
@@ -32,39 +35,39 @@ const honeyPotChecked: Ref<boolean> = ref(false)
 const emit = defineEmits(['update'])
 
 const validateCaptchaState = () =>
-  verified.value && !honeyPotChecked.value ||
-  "Veuillez procédez à la vérification";
+  (verified.value && !honeyPotChecked.value) ||
+  'Veuillez procéder à la vérification'
 
 function onVerify(tokenStr: string, ekey: string) {
-  verified.value = true;
-  token.value = tokenStr;
-  eKey.value = ekey;
+  verified.value = true
+  token.value = tokenStr
+  eKey.value = ekey
   emit('update', true)
 }
 
 function onExpire() {
-  verified.value = false;
-  token.value = '';
-  eKey.value = '';
-  expired.value = true;
+  verified.value = false
+  token.value = ''
+  eKey.value = ''
+  expired.value = true
 }
 
 function onChallengeExpire() {
-  verified.value = false;
-  token.value = '';
-  eKey.value = '';
-  expired.value = true;
+  verified.value = false
+  token.value = ''
+  eKey.value = ''
+  expired.value = true
 }
 
 function onError(err: string) {
-  token.value = '';
-  eKey.value = '';
-  error.value = err;
-  console.log(`Error: ${err}`);
+  token.value = ''
+  eKey.value = ''
+  error.value = err
+  console.log(`Error: ${err}`)
 
   if (process.dev) {
     console.log('Dev mode: force captcha validation')
-    verified.value = true;
+    verified.value = true
   }
 }
 </script>

+ 81 - 29
components/Layout/FAQ.vue

@@ -1,14 +1,14 @@
 <template>
   <div class="alt-theme main my-2">
-    <div class="d-flex flex-row">
-      <div class="d-flex flex-column">
+    <v-row>
+      <v-col cols="12" lg="6">
         <LayoutUISubTitle class="mt-12 ml-3">
           Vous voulez tirer le meilleur de notre logiciel ?
         </LayoutUISubTitle>
 
         <h3 class="mt-6">
-          Quelle que soit votre demande, notre équipe est à vos côtés pour
-          vous guider
+          Quelle que soit votre demande, notre équipe est à vos côtés pour vous
+          guider
         </h3>
 
         <v-btn
@@ -18,53 +18,51 @@
         >
           Consulter notre FAQ
         </v-btn>
-      </div>
+      </v-col>
 
-      <div class="d-flex flex-column justify-center links">
+      <v-col cols="12" lg="6" class="links">
         <v-btn
-          href="https://ressources.opentalent.fr/pages/viewpage.action?pageId=75170564"
+          href="https://ressources.opentalent.fr/space/FAQ/2496592/Tutoriels+vid%C3%A9os"
           target="_blank"
         >
           <div>
             <v-img
-              src="/images/icons/tuto.svg"
+              src="/images/components/faq/Icone_tutoriels-videos.svg"
+              alt="Icône livre avec logo Youtube"
             />
 
-            <p>
-              De nombreux articles tutoriels accessibles 24h/24
-            </p>
+            <p>De nombreux articles tutoriels accessibles 24h/24</p>
           </div>
         </v-btn>
 
-        <v-btn
-          href="https://ressources.opentalent.fr/?contact"
-          target="_blank"
-        >
+        <v-btn href="https://ressources.opentalent.fr/" target="_blank">
           <div>
             <v-img
-              src="/images/icons/faq.svg"
+              src="/images/components/faq/Icone_FAQ.svg"
+              alt="Icône deux bulles de conversation avec indiquée FAQ à l’intérieur d’une"
             />
 
             <p class="text-btn">
-              Support accessible du lundi au vendredi via l’outil en
-              ligne
+              Support accessible du lundi au vendredi via l’outil en ligne
             </p>
           </div>
         </v-btn>
-      </div>
-    </div>
+      </v-col>
+    </v-row>
   </div>
 </template>
 
+<script setup lang="ts"></script>
 <style scoped lang="scss">
-.flex-row {
+.v-row {
   position: relative;
   z-index: 2;
+  max-width: 100%;
 }
 
 .main {
   min-height: 600px;
-  background-image: url("/images/logiciels/school/faq.jpg");
+  background-image: url('/images/components/faq/Orchestre_de_rue_avec_danseuse.jpg');
   background-size: cover;
   background-position: center 15%;
   background-repeat: no-repeat;
@@ -77,7 +75,7 @@
 }
 
 .main::after {
-  content: "";
+  content: '';
   position: absolute;
   top: 0;
   left: 0;
@@ -88,42 +86,72 @@
 }
 
 h3 {
-  margin-left: 3rem;
+  margin-left: 20px;
   margin-right: 15rem;
   width: 28rem;
   margin-bottom: 3rem;
   font-size: 30px;
   font-weight: 400;
+
+  @media (max-width: 600px) {
+    width: 90%;
+    margin-right: auto;
+    margin-left: auto;
+  }
 }
 
 .btn-faq {
   width: 14rem;
   height: 3.5rem;
-  margin-left: 3rem;
+  margin-left: 20px;
   border-radius: 6px;
   font-weight: 500;
   font-size: 0.8rem;
-  z-index: 1;
+  z-index: 2;
   text-transform: none !important;
   line-height: 1rem;
+  margin-right: auto;
+
+  @media (max-width: 1240px) {
+    width: 40%;
+    margin-left: 30%;
+  }
+
+  @media (max-width: 600px) {
+    width: 90%;
+    margin-left: 5%;
+  }
 }
 
 .links {
+  justify-content: center;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+
+  @media (max-width: 1240px) {
+    flex-direction: row;
+  }
+
+  @media (max-width: 1240px) {
+    flex-direction: column;
+  }
+
   .v-btn {
-    z-index: 1;
+    z-index: 2;
     width: 23rem;
     height: 5.5rem;
     margin-left: 3rem;
     border-radius: 6px;
-    background: transparent;
     font-weight: 500;
     font-size: 0.8rem;
     line-height: 1rem;
     border: 1px var(--on-alt-theme) solid;
     margin-bottom: 2rem;
     text-transform: none !important;
+    background: rgba(0, 0, 0, 0.6);
 
-    .v-btn__content>div {
+    .v-btn__content > div {
       display: flex;
       flex-direction: row;
       align-items: center;
@@ -145,6 +173,30 @@ h3 {
       white-space: normal !important;
       text-align: left;
     }
+
+    @media (max-width: 1240px) {
+      max-width: 40%;
+      margin: 12px 5%;
+      height: 8rem;
+
+      .v-btn__content > div {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+      }
+
+      .v-img {
+        margin-bottom: 6px;
+      }
+
+      p {
+        text-align: center;
+      }
+    }
+
+    @media (max-width: 600px) {
+      max-width: 90%;
+    }
   }
 }
 </style>

+ 128 - 134
components/Layout/Footer/Footer.vue

@@ -6,43 +6,36 @@
         <v-row>
           <!-- Première section : Logo Opentalent -->
           <v-col cols="12" lg="3" class="logo">
-            <nuxt-link to="/">
-              <v-img src="/images/logo/footer-logo.png" />
+            <nuxt-link :to="{ path: '/', hash: '#top' }">
+              <v-img
+                src="/images/logos/opentalent/Logo_Opentalent-blanc.png"
+                alt="Logo Opentalent - Agenda et Logiciels culturels"
+              />
             </nuxt-link>
           </v-col>
 
           <!-- Deuxième section : liens agenda culturel (écrans larges seulement) -->
-          <v-col v-if="mdAndUp" cols="7" >
+          <v-col v-if="lgAndUp" cols="7">
             <v-row>
               <v-col cols="3">
                 <v-row>
-                  <h5>
-                    Agenda culturel
-                  </h5>
+                  <h5>Agenda</h5>
                 </v-row>
                 <v-row>
-                  <AgendaLink href="/annuaire">
-                    Annuaire
-                  </AgendaLink>
+                  <AgendaLink href="/annuaire"> Annuaire </AgendaLink>
                 </v-row>
                 <v-row>
-                  <AgendaLink href="/actualites">
-                    Actualités
-                  </AgendaLink>
+                  <AgendaLink href="/actualites"> Actualités </AgendaLink>
                 </v-row>
                 <v-row>
-                  <AgendaLink href="/annonces">
-                    Annonces
-                  </AgendaLink>
+                  <AgendaLink href="/annonces"> Annonces </AgendaLink>
                 </v-row>
               </v-col>
 
               <!-- Troisième section : liens logiciels culturels (écrans larges seulement) -->
               <v-col cols="3">
                 <v-row>
-                  <h5>
-                    Logiciels culturels
-                  </h5>
+                  <h5>Logiciels</h5>
                 </v-row>
                 <v-row>
                   <nuxt-link to="/opentalent_artist">
@@ -52,8 +45,7 @@
                 <v-row>
                   <nuxt-link to="/opentalent_school">
                     Opentalent School
-                  </nuxt-link
-                  >
+                  </nuxt-link>
                 </v-row>
                 <v-row>
                   <nuxt-link to="/opentalent_manager">
@@ -65,60 +57,48 @@
               <!-- Quatrième section : A propos (écrans larges seulement) -->
               <v-col cols="3">
                 <v-row>
-                  <h5>
-                    A PROPOS
-                  </h5>
+                  <h5>A PROPOS</h5>
                 </v-row>
                 <v-row>
-                  <nuxt-link to="/qui-sommes-nous">
-                    Qui sommes-nous
-                  </nuxt-link>
+                  <nuxt-link to="/qui-sommes-nous"> Qui sommes-nous </nuxt-link>
                 </v-row>
                 <v-row>
-                  <nuxt-link to="/nous-rejoindre">
-                    Nous rejoindre
-                  </nuxt-link
-                  >
+                  <nuxt-link to="/nous-rejoindre"> Nous rejoindre </nuxt-link>
                 </v-row>
                 <v-row>
-                  <nuxt-link to="/nous-contacter">
-                    Nous contacter
-                  </nuxt-link>
+                  <nuxt-link to="/nous-contacter"> Nous contacter </nuxt-link>
                 </v-row>
               </v-col>
 
               <!-- Cinquième section : liens espace client (écrans larges seulement) -->
               <v-col cols="3">
                 <v-row>
-                  <h5>
-                    Espace client
-                  </h5>
+                  <h5>Espace client</h5>
                 </v-row>
                 <v-row>
-                  <nuxt-link href="https://ressources.opentalent.fr/display/FAQ/Accueil" target="_blank">
+                  <nuxt-link
+                    href="https://ressources.opentalent.fr/display/FAQ/Accueil"
+                    target="_blank"
+                  >
                     Foire Aux Questions
                   </nuxt-link>
                 </v-row>
                 <v-row>
-                  <nuxt-link href="https://ressources.opentalent.fr/" target="_blank">
+                  <nuxt-link
+                    href="https://ressources.opentalent.fr/"
+                    target="_blank"
+                  >
                     Support en ligne
                   </nuxt-link>
                 </v-row>
-                <v-row>
-                  <nuxt-link to="/nous-contacter" target="_blank" >
-                    Nous contacter
-                  </nuxt-link>
-                </v-row>
               </v-col>
             </v-row>
           </v-col>
 
           <!-- Sixième section : liens réseaux sociaux (écrans larges seulement) -->
-          <v-col v-if="mdAndUp" cols="2">
+          <v-col v-if="lgAndUp" cols="2">
             <v-row class="justify-center">
-              <h5>
-                Suivez-nous
-              </h5>
+              <h5>Suivez-nous</h5>
             </v-row>
 
             <v-row class="justify-center social-networks">
@@ -156,10 +136,7 @@
         </v-row>
 
         <!-- Deuxième section alt : version petits écrans -->
-        <v-row
-          v-if="mdAndDown"
-          class="justify-center social-networks"
-        >
+        <v-row v-if="mdAndDown" class="justify-center social-networks">
           <!-- TODO: voir si faisable de fusionner avec la section précédente -->
           <v-col cols="12" class="text-center">
             <nuxt-link
@@ -187,56 +164,57 @@
       </div>
 
       <!-- Troisième section alt : version petits écrans -->
-<!--      <v-row v-if="mdAndDown">-->
-<!--        <v-col cols="12" >-->
-<!--          <div v-for="(item, index) in footerLinks" :key="index">-->
-<!--            <v-container>-->
-<!--              <div class="section" @click="toggleSection(index)">-->
-<!--                <div class="d-flex flex-row justify-space-between">-->
-<!--                  {{ item.label }}-->
-
-<!--                  <v-icon-->
-<!--                    :icon="isActive(index) ? 'fas fa-chevron-up' : 'fas fa-chevron-down'"-->
-<!--                  />-->
-<!--                </div>-->
-
-<!--                <div-->
-<!--                  v-show="isActive(index)"-->
-<!--                  v-for="(sublink, sublinkIndex) in item.sublink"-->
-<!--                  :key="sublinkIndex"-->
-<!--                  class="mt-3"-->
-<!--                >-->
-<!--                  <nuxt-link :href="sublink.link">-->
-<!--                    {{ sublink.label }}-->
-<!--                  </nuxt-link>-->
-<!--                </div>-->
-<!--              </div>-->
-<!--            </v-container>-->
-
-<!--          </div>-->
-<!--        </v-col>-->
-<!--      </v-row>-->
+      <v-row v-if="mdAndDown">
+        <v-col cols="12">
+          <div v-for="(item, index) in footerLinks" :key="index">
+            <v-container>
+              <div class="section" @click="toggleSection(index)">
+                <div class="d-flex flex-row justify-space-between">
+                  {{ item.label }}
+
+                  <v-icon
+                    :icon="
+                      isActive(index)
+                        ? 'fas fa-chevron-up'
+                        : 'fas fa-chevron-down'
+                    "
+                  />
+                </div>
+
+                <div
+                  v-for="(sublink, sublinkIndex) in item.sublink"
+                  v-show="isActive(index)"
+                  :key="sublinkIndex"
+                  class="mt-3"
+                >
+                  <CommonAgendaLink :href="sublink.link">
+                    {{ sublink.label }}
+                  </CommonAgendaLink>
+                </div>
+              </div>
+            </v-container>
+          </div>
+        </v-col>
+      </v-row>
 
       <div class="footnotes">
         <v-row justify="center">
           <p class="mt-6">
-            <nuxt-link to="/mentions-legales">
-              Mentions légales
-            </nuxt-link>
+            <nuxt-link to="/mentions-legales"> Mentions légales </nuxt-link>
             -
-            <nuxt-link to="/politique-de-confidentialite-et-protection-des-donnees-personnelles">
-              Politiques de cookies
+            <nuxt-link
+              to="/politique-de-confidentialite-et-protection-des-donnees-personnelles"
+            >
+              Politiques de confidentialité
             </nuxt-link>
             -
-            <nuxt-link to="/CGV">
-              Conditions Générales de Ventes
-            </nuxt-link>
+            <nuxt-link to="/CGV"> Conditions Générales de Ventes </nuxt-link>
           </p>
         </v-row>
 
-        <v-row class="mb-6" justify="center">
+        <v-row class="mb-3" justify="center">
           <p>
-            2024 © Opentalent est une marque déposée par 2iOPENservice          
+            2024 © Opentalent est une marque déposée par 2iOPENservice
           </p>
         </v-row>
       </div>
@@ -245,111 +223,114 @@
 </template>
 
 <script setup>
-import { useDisplay } from "vuetify";
-import { useLayoutStore } from "~/stores/layoutStore";
-import AgendaLink from "~/components/Common/AgendaLink.vue";
-
+import { useDisplay } from 'vuetify'
+import { useLayoutStore } from '~/stores/layoutStore'
+import AgendaLink from '~/components/Common/AgendaLink.vue'
 
-const { mdAndDown, mdAndUp } = useDisplay();
+const { mdAndDown, lgAndUp } = useDisplay()
 
 const footerLinks = ref([
   {
-    label: "AGENDA CULTUREL",
+    label: 'AGENDA CULTUREL',
     sublink: [
       {
-        label: "Annuaire",
-        link: "/annuaire",
+        label: 'Annuaire',
+        link: '/annuaire',
       },
       {
-        label: "Actualités",
-        link: "/actualites",
+        label: 'Actualités',
+        link: '/actualites',
       },
       {
-        label: "Annonces",
-        link: "/annonces",
+        label: 'Annonces',
+        link: '/annonces',
       },
     ],
   },
   {
-    label: "LOGICIELS CULTURELS ",
+    label: 'LOGICIELS CULTURELS ',
     sublink: [
       {
-        label: "Opentalent Artist",
-        link: "/opentalent_artist",
+        label: 'Opentalent Artist',
+        link: '/opentalent_artist',
       },
       {
-        label: "Opentalent School",
-        link: "/opentalent_school",
+        label: 'Opentalent School',
+        link: '/opentalent_school',
       },
       {
-        label: "Opentalent Manager",
-        link: "/opentalent_manager",
+        label: 'Opentalent Manager',
+        link: '/opentalent_manager',
       },
     ],
   },
   {
-    label: "À PROPOS ",
+    label: 'À PROPOS ',
     sublink: [
       {
-        label: "Qui sommes-nous",
-        link: "/qui-sommes-nous",
+        label: 'Qui sommes-nous',
+        link: '/qui-sommes-nous',
       },
       {
-        label: "Nous rejoindre",
-        link: "/nous-rejoindre",
+        label: 'Nous rejoindre',
+        link: '/nous-rejoindre',
       },
       {
-        label: "Nous contacter",
-        link: "/nous-contacter",
+        label: 'Nous contacter',
+        link: '/nous-contacter',
       },
     ],
   },
   {
-    label: "ESPACE CLIENT ",
+    label: 'ESPACE CLIENT ',
     sublink: [
       {
-        label: "Foire Aux Questions ",
-        link: "/ https://ressources.opentalent.fr",
+        label: 'Foire Aux Questions ',
+        link: '/ https://ressources.opentalent.fr',
       },
       {
-        label: "Support en ligne ",
-        link: "/https://ressources.opentalent.fr/?contact",
+        label: 'Support en ligne ',
+        link: '/https://ressources.opentalent.fr/?contact',
       },
       {
-        label: "Nous contacter ",
-        link: "/nous-contacter",
+        label: 'Nous contacter ',
+        link: '/nous-contacter',
       },
     ],
   },
-]);
+])
 
-const activeIndex = ref(-1);
+const activeIndex = ref(-1)
 function toggleSection(index) {
-  activeIndex.value = activeIndex.value === index ? -1 : index;
+  activeIndex.value = activeIndex.value === index ? -1 : index
 }
 
 function isActive(index) {
-  return activeIndex.value === index;
+  return activeIndex.value === index
 }
 
 const layoutStore = useLayoutStore()
 const onIntersect = (isIntersecting) => {
   layoutStore.setIsFooterVisible(isIntersecting)
 }
-
 </script>
 
 <style scoped lang="scss">
-
 .container {
   background: var(--primary-color);
   color: var(--on-primary-color);
 }
 
+.logo {
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  margin-bottom: 20px;
+}
+
 .logo .v-img {
-  margin-bottom: 3rem;
+  height: 120px;
   width: 300px;
-  height: 100px;
 }
 
 .v-col {
@@ -385,16 +366,29 @@ a {
     font-size: 1.9rem;
     text-decoration: none !important;
   }
+
+  @media (max-width: 1240px) {
+    a {
+      margin: 0 3%;
+      font-size: 2.4rem;
+    }
+  }
 }
 
 .footnotes {
   border-top: 0.4px solid var(--neutral-color-alt-strong);
   box-shadow: 0 3px 24px rgba(0, 0, 0, 0.07);
 
-  a, p {
+  a,
+  p {
     text-decoration: none;
     color: var(--on-primary-color);
     font-size: 0.8rem;
+
+    @media (max-width: 600px) {
+      max-width: 90%;
+      text-align: center;
+    }
   }
 }
 
@@ -426,8 +420,8 @@ a {
     font-size: 1.5rem;
     cursor: pointer;
 
-    >div:first-child {
-      border-bottom: 1px solid var(--on-secondary-color);
+    > div:first-child {
+      border-bottom: 1px solid var(--on-primary-color);
       padding-bottom: 6px;
       text-transform: uppercase;
     }

+ 55 - 6
components/Layout/Footer/Prefooter.vue

@@ -4,12 +4,15 @@ Première section du footer (galerie des logiciels)
 
 <template>
   <footer>
-    <LayoutContainer>
+    <!-- Ecrans larges -->
+    <LayoutContainer v-if="lgAndUp">
       <v-row>
-
         <v-col cols="4" class="text-center">
           <nuxt-link to="/opentalent_artist">
-            <v-img src="/images/logo/logiciels/Artist-noir.png"/>
+            <v-img
+              src="/images/logos/opentalent/Logo_Opentalent_Artist-gris.png"
+              alt="Logo Opentalent Artist - logiciel de gestion et de communication pour les orchestres, les chorales, les compagnies artistiques et troupes"
+            />
           </nuxt-link>
 
           <small class="text-logo">
@@ -21,7 +24,10 @@ Première section du footer (galerie des logiciels)
 
         <v-col cols="4" class="text-center">
           <nuxt-link to="/opentalent_school">
-            <v-img src="/images/logo/logiciels/School-noir.png"/>
+            <v-img
+              src="/images/logos/opentalent/Logo_Opentalent_School-gris.png"
+              alt="Logo Opentalent School - logiciel de gestion et de communication pour les établissements d’enseignement artistique "
+            />
           </nuxt-link>
 
           <small class="text-logo">
@@ -33,7 +39,10 @@ Première section du footer (galerie des logiciels)
 
         <v-col cols="3" class="text-center">
           <nuxt-link to="/opentalent_manager">
-            <v-img src="/images/logo/logiciels/Manager-noir.png"/>
+            <v-img
+              src="/images/logos/opentalent/Logo_Opentalent_Manager-gris.png"
+              alt="Logo Opentalent Manager - logiciel de gestion et de communication pour les fédérations, les confédérations et les collectivités"
+            />
           </nuxt-link>
 
           <small class="text-logo">
@@ -42,10 +51,50 @@ Première section du footer (galerie des logiciels)
         </v-col>
       </v-row>
     </LayoutContainer>
+
+    <!-- Petits écrans -->
+    <LayoutContainer v-else>
+      <v-row class="justify-center">
+        <v-col cols="3" class="border-right">
+          <nuxt-link to="/opentalent_artist">
+            <v-img
+              src="/images/logos/opentalent/Logo_Opentalent_Artist_Griffe.png"
+            />
+          </nuxt-link>
+        </v-col>
+
+        <v-col cols="1">
+          <v-divider :vertical="true" />
+        </v-col>
+
+        <v-col cols="3">
+          <nuxt-link to="/opentalent_school">
+            <v-img
+              src="/images/logos/opentalent/Logo_Opentalent_School_Griffe.png"
+            />
+          </nuxt-link>
+        </v-col>
+
+        <v-col cols="1">
+          <v-divider :vertical="true" />
+        </v-col>
+
+        <v-col cols="3">
+          <nuxt-link to="/opentalent_manager">
+            <v-img
+              src="/images/logos/opentalent/Logo_Opentalent_Manager_Griffe.png"
+            />
+          </nuxt-link>
+        </v-col>
+      </v-row>
+    </LayoutContainer>
   </footer>
 </template>
 
-<script setup>
+<script setup lang="ts">
+import { useDisplay } from 'vuetify'
+
+const { lgAndUp } = useDisplay()
 </script>
 
 <style scoped lang="scss">

+ 0 - 183
components/Layout/Footer/Solutions.vue

@@ -1,183 +0,0 @@
-<template>
-  <div id="solutions">
-    <LayoutContainer>
-      <v-row class="center-90">
-        <v-col cols="12">
-          <LayoutUISubTitle>
-            NOS LOGICIELS OPENTALENT
-          </LayoutUISubTitle>
-
-          <LayoutUITitle>
-            Ces solutions peuvent aussi vous intéresser
-          </LayoutUITitle>
-        </v-col>
-      </v-row>
-
-      <v-row
-        v-if="showArtist"
-        class="row-artist"
-      >
-        <v-col cols="2">
-          <NuxtLink to="/opentalent_artist">
-            <v-img src="/images/logo/logiciels/Artist-noir.png" class="logo" />
-          </NuxtLink>
-        </v-col>
-
-        <v-col cols="10">
-          <!-- list v-chip-->
-          <v-chip-group column disabled>
-            <v-chip class="ma-2 chip-custom" label>
-              <span class="chip-detail">Orchestres</span>
-            </v-chip>
-            <v-chip class="ma-2 chip-custom" label>
-              <span class="chip-detail">Chorales</span>
-            </v-chip>
-            <v-chip class="ma-2 chip-custom" label>
-              <span class="chip-detail">Compagnies de danse</span>
-            </v-chip>
-            <v-chip class="ma-2 chip-custom" label>
-              <span class="chip-detail">Compagnies de théatre</span>
-            </v-chip>
-            <v-chip class="ma-2 chip-custom" label>
-              <span class="chip-detail">Compagnies de Cirque</span>
-            </v-chip>
-          </v-chip-group>
-        </v-col>
-      </v-row>
-
-      <v-row
-        v-if="showManager"
-        class="row-manager"
-      >
-        <v-col cols="2">
-          <NuxtLink to="/opentalent_manager">
-          <v-img src="/images/logo/logiciels/Manager-noir.png" class="logo" />
-        </NuxtLink>
-        </v-col>
-
-        <v-col cols="10">
-          <!-- list v-chip-->
-          <v-chip-group column disabled>
-            <v-chip class="ma-2 chip-custom" color="primary" label>
-              <span class="chip-detail">Fédérations</span>
-            </v-chip>
-            <v-chip class="ma-2 chip-custom" color="primary" label>
-              <span class="chip-detail">Confédérations</span>
-            </v-chip>
-            <v-chip class="ma-2 chip-custom" color="primary" label>
-              <span class="chip-detail">Collectivités</span>
-            </v-chip>
-            <v-chip class="ma-2 chip-custom" color="primary" label>
-              <span class="chip-detail">Réseaux</span>
-            </v-chip>
-          </v-chip-group>
-        </v-col>
-      </v-row>
-
-      <v-row
-        v-if="showSchool"
-        class="row-school"
-      >
-        <v-col cols="2">
-          <NuxtLink to="/opentalent_school">
-            <v-img src="/images/logo/logiciels/School-noir.png" class="logo" />
-          </NuxtLink>
-        </v-col>
-
-        <v-col cols="10">
-          <!-- list v-chip-->
-          <v-chip-group column disabled>
-            <v-chip class="ma-2 chip-custom" label>
-              <span class="chip-detail">Conservatoire</span>
-            </v-chip>
-            <v-chip class="ma-2 chip-custom" label>
-              <span class="chip-detail">Écoles d'art</span>
-            </v-chip>
-            <v-chip class="ma-2 chip-custom" label>
-              <span class="chip-detail">École de musique</span>
-            </v-chip>
-            <v-chip class="ma-2 chip-custom" label>
-              <span class="chip-detail">École de danse</span>
-            </v-chip>
-            <v-chip class="ma-2 chip-custom" label>
-              <span class="chip-detail">École de théâtre</span>
-            </v-chip>
-            <v-chip class="ma-2 chip-custom" label>
-              <span class="chip-detail">École de cirque</span>
-            </v-chip>
-            <v-chip class="ma-2 chip-custom" label>
-              <span class="chip-detail">MJC</span>
-            </v-chip>
-          </v-chip-group>
-        </v-col>
-      </v-row>
-    </LayoutContainer>
-  </div>
-</template>
-
-<script setup lang="ts">
-const props = defineProps({
-  showArtist: {
-    type: Boolean,
-    required: false,
-    default: true
-  },
-  showSchool: {
-    type: Boolean,
-    required: false,
-    default: true
-  },
-  showManager: {
-    type: Boolean,
-    required: false,
-    default: true
-  },
-})
-</script>
-
-<style scoped lang="scss">
-.chip-detail {
-  color: var(--on-neutral-color);
-}
-
-.chip-custom {
-  opacity: 1;
-  color: var(--on-primary-color);
-  border: 1px solid var(--primary-color);
-  border-radius: 3rem;
-  text-transform: uppercase;
-  font-weight: 500;
-  font-size: 10px;
-  line-height: 16px;
-  display: flex;
-  align-items: center;
-  text-align: center;
-  letter-spacing: 0.2em;
-}
-
-.row-artist,
-.row-school,
-.row-manager {
-  display: flex;
-  flex-direction: row;
-  align-items: center;
-  border-top: 1px solid var(--on-primary-color-alt);
-}
-
-.solution-title {
-  font-weight: 500;
-  font-size: 1.5rem;
-  line-height: 1.5rem;
-  color: var(--on-neutral-color);
-  margin-top: 2rem;
-  margin-bottom: 2rem;
-  text-align: center;
-}
-
-.logo {
-  width: 15rem;
-  height: 10rem;
-  margin-left: .5rem;
-  margin-right: 2rem;
-}
-</style>

+ 31 - 250
components/Layout/Navigation.vue

@@ -2,276 +2,57 @@
 Menu Navigation
 -->
 <template>
-  <!-- Navigation (écran large) -->
-  <div v-if="mdAndUp" v-intersect="onIntersect">
-    <LayoutNavigationTopbar />
-
-    <v-row class="navigation-lg" style="margin-top: 0 !important;">
-      <!-- Logo Opentalent -->
-      <v-col cols="2">
-        <nuxt-link to="/">
-          <v-img class="logo" src="/images/logo/navigation-logo.png" />
-        </nuxt-link>
-      </v-col>
-
-      <!-- Menu principal -->
-      <v-col cols="10" class="pl-6">
-        <v-menu
-          v-for="item in menu"
-          :key="item.label"
-          :open-on-hover="true"
-        >
-          <template v-slot:activator="{ props }">
-            <nuxt-link
-              v-bind="props"
-              class="menuItem first-level"
-              :to="item.to"
-            >
-              {{ item.label }}
-            </nuxt-link>
-          </template>
-
-          <v-list
-            v-if="item.children?.length > 0"
-            class="menu-list"
-          >
-            <v-list-item
-              v-for="child in item.children"
-              :key="child.label"
-              :to="child.to"
-              class="menuItem"
-            >
-              <v-list-item-title>{{ child.label }}</v-list-item-title>
-            </v-list-item>
-          </v-list>
-        </v-menu>
-      </v-col>
-    </v-row>
+  <div v-intersect="onIntersect">
+    <!-- Navigation (écran large) -->
+    <div v-if="lgAndUp">
+      <LayoutNavigationLg :menu="menu" />
+    </div>
+
+    <!-- Navigation (petit écran) -->
+    <div v-else>
+      <LayoutNavigationMd :menu="menu" />
+    </div>
   </div>
-
-  <!-- Navigation (petit écran) -->
-  <v-app
-    v-else
-    class="navigation-sm"
-  >
-    <!-- Top bar -->
-    <v-app-bar app>
-      <v-app-bar-nav-icon
-        @click="toggleMenu"
-      />
-
-      <nuxt-link to="/">
-        <v-img class="logo-md" src="/images/logo/navigation-logo.png" />
-      </nuxt-link>
-
-      <nuxt-link
-        to="https://admin.opentalent.fr/#/login/"
-        style="text-decoration: none"
-      >
-        <v-btn text>
-          <v-icon left class="fas fa-user icon"></v-icon>
-        </v-btn>
-      </nuxt-link>
-
-      <v-btn text>
-        <v-icon left class="fas fa-phone icon"></v-icon>
-      </v-btn>
-
-      <AgendaLink href="/agenda-culturel" style="text-decoration: none">
-        <v-btn text>
-          <v-icon left class="fas fa-calendar icon"></v-icon>
-        </v-btn>
-      </AgendaLink>
-    </v-app-bar>
-
-    <!-- Tiroir de navigation principal -->
-    <v-navigation-drawer
-      v-model="isMenuOpen"
-      app
-      temporary
-    >
-      <v-list nav dense>
-        <v-list-item
-          v-if="isSubMenu"
-          class="menuItem back-item"
-          @click="onBackItemClick"
-        >
-          <v-list-item-title>
-            <v-icon icon="fas fa-caret-left" class="mr-1"/> Retour
-          </v-list-item-title>
-        </v-list-item>
-
-        <v-list-item
-          v-for="(item, index) in activeMenu"
-          :key="item.label"
-          :to="item.to"
-          class="menuItem"
-          @click="onMenuItemClick(index, item)"
-        >
-          <v-list-item-title>
-            {{ item.label }}
-          </v-list-item-title>
-        </v-list-item>
-      </v-list>
-    </v-navigation-drawer>
-  </v-app>
 </template>
 
 <script setup lang="ts">
-import { useDisplay } from "vuetify";
-import type { MainMenuItem } from "~/types/interface";
-import AgendaLink from "~/components/Common/AgendaLink.vue";
-import Footer from "~/components/Layout/Footer/Footer.vue";
-import { useLayoutStore } from "~/stores/layoutStore";
-const { mdAndUp } = useDisplay();
+import { useDisplay } from 'vuetify'
+import type { MainMenuItem } from '~/types/interface'
+import { useLayoutStore } from '~/stores/layoutStore'
+
+const { lgAndUp } = useDisplay()
 
 const menu: Array<MainMenuItem> = [
   {
-    label: "Nos logiciels",
+    label: 'Nos logiciels',
     children: [
-      { label: "Opentalent Artist", to: "/opentalent_artist" },
-      { label: "Opentalent School", to: "/opentalent_school" },
-      { label: "Opentalent Manager", to: "/opentalent_manager" },
-    ]
+      { label: 'Opentalent Artist', to: '/opentalent_artist' },
+      { label: 'Opentalent School', to: '/opentalent_school' },
+      { label: 'Opentalent Manager', to: '/opentalent_manager' },
+    ],
   },
   {
-    label: "Nos services",
+    label: 'Nos services',
     children: [
-      { label: "Formations", to: "/formations" },
-      { label: "Webinaires", to: "/webinaires" },
-    ]
+      { label: 'Formations', to: '/formations' },
+      { label: 'Webinaires', to: '/webinaires' },
+    ],
   },
   {
-    label: "À propos",
+    label: 'À propos',
     children: [
-      { label: "Qui sommes-nous", to: "/qui-sommes-nous" },
-      { label: "Nous rejoindre", to: "/nous-rejoindre" },
-    ]
+      { label: 'Qui sommes-nous', to: '/qui-sommes-nous' },
+      { label: 'Nous rejoindre', to: '/nous-rejoindre' },
+    ],
   },
-  { label: "Actualités", to: "/actualites" },
-  { label: "Contact", to: "/nous-contacter" },
+  { label: 'Actualités', to: '/actualites' },
+  { label: 'Contact', to: '/nous-contacter' },
 ]
 
-// Menu dépliant (petit écran)
-const isMenuOpen: Ref<boolean> = ref(false);
-const toggleMenu = () => {
-  isMenuOpen.value = !isMenuOpen.value;
-};
-
-const activeMenuIndex: Ref<number | null> = ref(null)
-
-const activeMenu = computed(() =>
-  activeMenuIndex.value !== null ? menu[activeMenuIndex.value].children : menu
-)
-
-/**
- * Determines if the is active menu is a sub-menu .
- *
- * @function isSubMenu
- * @returns {boolean} - True if a sub-menu is active, otherwise false.
- */
-const isSubMenu = computed(() => activeMenuIndex.value !== null)
-
-/**
- * Handles the click event on a menu item.
- *
- * @param {number} index - The index of the clicked menu item.
- * @param {MainMenuItem} item - The clicked menu item.
- * @returns {void}
- */
-const onMenuItemClick = (index: number, item: MainMenuItem): void => {
-  if (!item.children) {
-    return
-  }
-  withAnimation(() => activeMenuIndex.value = index)
-}
-
-/**
- * Function to handle back button click event.
- */
-const onBackItemClick = (): void => {
-  withAnimation(() => activeMenuIndex.value = null)
-}
-
-/**
- * Déclenche une animation de changement de menu en fermant et rouvrant le drawer
- * @param callback
- */
-const withAnimation = (callback: () => void) => {
-  isMenuOpen.value = false
-  callback()
-  setTimeout(() => {isMenuOpen.value = true}, 85)
-}
-
 const layoutStore = useLayoutStore()
 const onIntersect = (isIntersecting: boolean) => {
   layoutStore.setIsHeaderVisible(isIntersecting)
 }
-
 </script>
 
-<style scoped>
-
-.logo {
-  height: 100px;
-  width: 300px;
-}
-
-.logo-md {
-  width: 150px;
-  height: 300px;
-}
-
-.icon {
-  color: var(--on-neutral-color);
-}
-
-.menuItem, .menuItem .v-list-item-title {
-  font-weight: 500;
-  font-size: 0.9rem;
-  letter-spacing: 0.1em;
-  text-transform: uppercase;
-  color: var(--primary-color);
-  cursor: pointer;
-  text-decoration: none !important;
-}
-
-/**
-  Navigation grands écrans
- */
-.navigation-lg {
-  display: flex;
-  align-items: center;
-  background-color: var(--neutral-color);
-
-  .menuItem  {
-    padding: 18px;
-  }
-
-  .menuItem.first-level {
-    font-size: 1.3rem;
-    margin-right: 1rem;
-    font-weight: 700;
-    letter-spacing: 0.05em;
-  }
-}
-
-/**
-  Navigation petits écrans
- */
-.navigation-sm {
-  background-color: var(--neutral-color);
-  position: fixed;
-  top: 0;
-}
-
-.back-item {
-  border-bottom: solid 1px var(--on-neutral-color-light);
-  border-radius: 0;
-
-  .v-list-item-title {
-    display: flex;
-    align-items: center;
-  }
-}
-</style>
+<style scoped></style>

+ 96 - 0
components/Layout/Navigation/Lg.vue

@@ -0,0 +1,96 @@
+<!-- Barre de navigation (écran large) -->
+<template>
+  <div>
+    <LayoutNavigationTopbar />
+
+    <v-row class="navigation-lg" style="margin-top: 0 !important">
+      <!-- Logo Opentalent -->
+      <v-col cols="2">
+        <nuxt-link to="/">
+          <v-img
+            src="/images/logos/opentalent/Logo_Opentalent-gris.png"
+            alt="Logo Opentalent - Agenda et logiciels culturels"
+            class="logo ml-4"
+          />
+        </nuxt-link>
+      </v-col>
+
+      <!-- Menu principal -->
+      <v-col cols="10" class="pl-6">
+        <v-menu v-for="item in menu" :key="item.label" :open-on-hover="true">
+          <template #activator="{ props }">
+            <nuxt-link
+              v-bind="props"
+              class="menuItem first-level"
+              :to="item.to"
+            >
+              {{ item.label }}
+            </nuxt-link>
+          </template>
+
+          <v-list v-if="item.children?.length! > 0" class="menu-list">
+            <v-list-item
+              v-for="child in item.children"
+              :key="child.label"
+              :to="child.to"
+              class="menuItem"
+            >
+              <v-list-item-title>{{ child.label }}</v-list-item-title>
+            </v-list-item>
+          </v-list>
+        </v-menu>
+      </v-col>
+    </v-row>
+  </div>
+</template>
+
+<script setup lang="ts">
+import type { PropType } from 'vue'
+import type { MainMenuItem } from '~/types/interface'
+
+defineProps({
+  menu: {
+    type: Array as PropType<Array<MainMenuItem>>,
+    required: true,
+  },
+})
+</script>
+
+<style scoped lang="scss">
+.logo {
+  height: 100px;
+  width: 300px;
+}
+
+.icon {
+  color: var(--on-neutral-color);
+}
+
+.menuItem,
+.menuItem .v-list-item-title {
+  font-weight: 500;
+  font-size: 0.9rem;
+  letter-spacing: 0.1em;
+  text-transform: uppercase;
+  color: var(--primary-color);
+  cursor: pointer;
+  text-decoration: none !important;
+}
+
+.navigation-lg {
+  display: flex;
+  align-items: center;
+  background-color: var(--neutral-color);
+
+  .menuItem {
+    padding: 18px;
+  }
+
+  .menuItem.first-level {
+    font-size: 1.3rem;
+    margin-right: 1rem;
+    font-weight: 700;
+    letter-spacing: 0.05em;
+  }
+}
+</style>

+ 179 - 0
components/Layout/Navigation/Md.vue

@@ -0,0 +1,179 @@
+<template>
+  <div class="app-container">
+    <v-app class="navigation-sm">
+      <!-- Top bar -->
+      <v-app-bar>
+        <template #prepend>
+          <v-app-bar-nav-icon @click="toggleMenu" />
+        </template>
+
+        <v-app-bar-title>
+          <nuxt-link to="/">
+            <v-img
+              class="logo-md"
+              src="/images/logos/opentalent/Logo_Opentalent-gris.png"
+            />
+          </nuxt-link>
+        </v-app-bar-title>
+
+        <template #append>
+          <v-btn
+            href="https://admin.opentalent.fr/#/login/"
+            icon="fas fa-user"
+            class="icon"
+          />
+
+          <v-btn to="/nous-contacter" icon="fas fa-phone" class="icon" />
+
+          <AgendaLink href="/agenda-culturel">
+            <v-btn icon="fas fa-calendar" class="icon" />
+          </AgendaLink>
+        </template>
+      </v-app-bar>
+
+      <!-- Tiroir de navigation principal -->
+      <v-navigation-drawer v-model="isMenuOpen" app temporary>
+        <v-list nav dense>
+          <v-list-item
+            v-if="isSubMenu"
+            class="menuItem back-item"
+            @click="onBackItemClick"
+          >
+            <v-list-item-title>
+              <v-icon icon="fas fa-caret-left" class="mr-1" /> Retour
+            </v-list-item-title>
+          </v-list-item>
+
+          <v-list-item
+            v-for="(item, index) in activeMenu"
+            :key="item.label"
+            :to="item.to"
+            class="menuItem"
+            @click="onMenuItemClick(index, item)"
+          >
+            <v-list-item-title class="d-flex flex-row w-100">
+              <span class="flex-grow-1">
+                {{ item.label }}
+              </span>
+              <span v-if="item.children?.length! > 0">
+                <v-icon icon="fa fa-angle-right" />
+              </span>
+            </v-list-item-title>
+          </v-list-item>
+        </v-list>
+      </v-navigation-drawer>
+    </v-app>
+  </div>
+</template>
+
+<script setup lang="ts">
+import type { PropType, Ref } from 'vue'
+import { useDisplay } from 'vuetify'
+import AgendaLink from '~/components/Common/AgendaLink.vue'
+import type { MainMenuItem } from '~/types/interface'
+
+const { mdAndDown } = useDisplay()
+
+const props = defineProps({
+  menu: {
+    type: Array as PropType<Array<MainMenuItem>>,
+    required: true,
+  },
+})
+
+const isMenuOpen: Ref<boolean> = ref(false)
+const toggleMenu = () => {
+  isMenuOpen.value = !isMenuOpen.value
+}
+
+const activeMenuIndex: Ref<number | null> = ref(null)
+
+const activeMenu = computed(() =>
+  activeMenuIndex.value !== null
+    ? props.menu![activeMenuIndex.value].children
+    : props.menu
+)
+
+/**
+ * Determines if the is active menu is a sub-menu .
+ *
+ * @function isSubMenu
+ * @returns {boolean} - True if a sub-menu is active, otherwise false.
+ */
+const isSubMenu = computed(() => activeMenuIndex.value !== null)
+
+/**
+ * Handles the click event on a menu item.
+ *
+ * @param {number} index - The index of the clicked menu item.
+ * @param {MainMenuItem} item - The clicked menu item.
+ * @returns {void}
+ */
+const onMenuItemClick = (index: number, item: MainMenuItem): void => {
+  if (!item.children) {
+    return
+  }
+  withAnimation(() => (activeMenuIndex.value = index))
+}
+
+/**
+ * Function to handle back button click event.
+ */
+const onBackItemClick = (): void => {
+  withAnimation(() => (activeMenuIndex.value = null))
+}
+
+/**
+ * Déclenche une animation de changement de menu en fermant et rouvrant le drawer
+ * @param callback
+ */
+const withAnimation = (callback: () => void) => {
+  isMenuOpen.value = false
+  callback()
+  setTimeout(() => {
+    isMenuOpen.value = true
+  }, 85)
+}
+
+const showBackToTheTop = ref(false)
+
+const handleScroll = () => {
+  showBackToTheTop.value = window.scrollY > 50
+}
+</script>
+
+<style scoped lang="scss">
+.app-container {
+  height: 54px;
+}
+
+.v-app-bar {
+  max-width: 100vw;
+}
+
+.navigation-sm {
+  background-color: var(--neutral-color);
+  position: fixed;
+  top: 0;
+  z-index: 1000;
+}
+
+.logo-md {
+  width: 150px;
+  height: 50px;
+}
+
+.back-item {
+  border-bottom: solid 1px var(--on-neutral-color-light);
+  border-radius: 0;
+
+  .v-list-item-title {
+    display: flex;
+    align-items: center;
+  }
+}
+
+.icon {
+  color: var(--on-neutral-color-light);
+}
+</style>

+ 15 - 18
components/Layout/Navigation/Topbar.vue

@@ -1,26 +1,23 @@
 <template>
-  <div class="top-bar" >
-      <v-btn
-        href="https://admin.opentalent.fr/#/login/"
-        prepend-icon="fas fa-user"
-        class="btn-login"
-      >
-        Se connecter
-      </v-btn>
+  <div class="top-bar">
+    <v-btn
+      href="https://admin.opentalent.fr/#/login/"
+      prepend-icon="fas fa-user"
+      class="btn-login"
+    >
+      Se connecter
+    </v-btn>
 
-      <AgendaLink href="/">
-        <v-btn
-          prepend-icon="fas fa-calendar"
-          class="btn-agenda"
-        >
-            Agenda Culturel
-        </v-btn>
-      </AgendaLink>
+    <AgendaLink href="/">
+      <v-btn prepend-icon="fas fa-calendar" class="btn-agenda">
+        Agenda Culturel
+      </v-btn>
+    </AgendaLink>
   </div>
 </template>
 
 <script setup lang="ts">
-import AgendaLink from "~/components/Common/AgendaLink.vue";
+import AgendaLink from '~/components/Common/AgendaLink.vue'
 </script>
 
 <style scoped lang="scss">
@@ -37,7 +34,7 @@ import AgendaLink from "~/components/Common/AgendaLink.vue";
   .v-btn {
     margin: 4px 8px;
     border-radius: 6px;
-    height: 44px;
+    height: 36px;
   }
 }
 

+ 11 - 12
components/Layout/Pagination.vue

@@ -9,26 +9,25 @@
 </template>
 
 <script setup lang="ts">
-import type { PropType } from "@vue/runtime-core";
-import type { Pagination } from "~/types/data";
+import type { PropType } from 'vue'
+import type { Pagination } from '~/types/data'
 
-const props = defineProps({
+defineProps({
   modelValue: {
     type: Number,
-    required: true
+    required: true,
   },
   pagination: {
     type: Object as PropType<Pagination>,
-    required: true
-  }
-});
+    required: true,
+  },
+})
 
-const emit = defineEmits(['update:modelValue']);
+const emit = defineEmits(['update:modelValue'])
 
 const onPageUpdated = (newPage: number) => {
-  emit('update:modelValue', newPage);
-};
+  emit('update:modelValue', newPage)
+}
 </script>
 
-<style scoped lang="scss">
-</style>
+<style scoped lang="scss"></style>

+ 4 - 7
components/Layout/UI/SectionTitle.vue

@@ -1,18 +1,14 @@
 <!-- Titre H2 -->
 <template>
   <div class="d-flex justify-center align-center flex-column">
-    <v-icon
-      size="6"
-      icon="fas fa-circle"
-    />
+    <v-icon size="6" icon="fas fa-circle" />
     <h3>
       <slot />
     </h3>
   </div>
 </template>
 
-<script setup lang="ts">
-</script>
+<script setup lang="ts"></script>
 
 <style scoped lang="scss">
 h3 {
@@ -30,9 +26,10 @@ h3 {
 }
 
 .fa-circle {
+  font-size: 16px;
   margin-top: 1rem;
   margin-right: 1rem;
-  color: var(--on-neutral-color-light) !important;
+  color: var(--secondary-color) !important;
 }
 
 .alt-theme .fa-circle {

+ 7 - 12
components/Layout/UI/SubTitle.vue

@@ -4,10 +4,7 @@ Titre H4 précédé d'une puce
 <template>
   <LayoutContainer>
     <div class="container">
-      <v-icon
-        :icon="icon"
-        :size="iconSize"
-      />
+      <v-icon :icon="icon" :size="iconSize" />
       <h2>
         <slot />
       </h2>
@@ -16,18 +13,16 @@ Titre H4 précédé d'une puce
 </template>
 
 <script setup lang="ts">
-const router = useRouter();
-
-const props = defineProps({
+defineProps({
   icon: {
     type: String,
-    default: "fas fa-circle",
+    default: 'fas fa-circle',
   },
   iconSize: {
     type: [String, Number],
     default: 5,
   },
-});
+})
 </script>
 
 <style scoped lang="scss">
@@ -35,7 +30,7 @@ const props = defineProps({
   display: flex;
   align-items: center;
   gap: 0.5rem;
-  margin-left: 1rem;
+  margin-left: 4px;
   color: var(--primary-color);
   font-size: 10px;
   font-weight: 600;
@@ -45,7 +40,8 @@ const props = defineProps({
 }
 
 .v-icon {
-  color: var(--on-primary-color-alt);
+  color: var(--on-primary-color-alt) !important;
+  margin-top: 1px;
 }
 
 h2 {
@@ -56,5 +52,4 @@ h2 {
   letter-spacing: 1px;
   text-transform: uppercase;
 }
-
 </style>

+ 12 - 8
components/Layout/UI/Title.vue

@@ -7,15 +7,19 @@
   </LayoutContainer>
 </template>
 
-<script setup lang="ts">
-</script>
+<script setup lang="ts"></script>
 
 <style scoped lang="scss">
-  h3 {
-    color: var(--on-neutral-color);
-    font-weight: 600;
-    font-size: 3rem;
-    line-height: 3rem;
-    margin-left: 1rem;
+h3 {
+  color: var(--on-neutral-color);
+  font-weight: 600;
+  font-size: 3rem;
+  margin-left: 1rem;
+
+  @media (max-width: 600px) {
+    font-size: 2rem;
+    margin-left: 1.5%;
+    width: 97%;
   }
+}
 </style>

+ 29 - 4
components/Layout/UI/TitlePage.vue

@@ -1,16 +1,23 @@
 <template>
-  <div class="mb-4">
+  <div :class="'mb-4' + mdAndDown ? ' mt-12' : ''">
     <h1>
       <slot />
     </h1>
-    <h2>
+    <h2 v-if="mdAndUp">
       <slot name="subtitle" />
     </h2>
   </div>
 </template>
 
+<script setup lang="ts">
+import { useDisplay } from 'vuetify'
+
+const { mdAndDown, mdAndUp } = useDisplay()
+</script>
+
 <style scoped lang="scss">
-h1, h2 {
+h1,
+h2 {
   text-align: center;
   text-transform: uppercase;
 }
@@ -31,7 +38,7 @@ h2 {
   margin-right: 1rem;
 }
 
-@media (max-width: 960px) {
+@media (max-width: 1240px) {
   h1 {
     font-size: 2rem;
     line-height: 2.5rem;
@@ -43,4 +50,22 @@ h2 {
   }
 }
 
+@media (max-width: 600px) {
+  h1,
+  h2 {
+    width: 80%;
+    margin: auto;
+  }
+
+  h1 {
+    font-size: 2rem;
+    line-height: 2.5rem;
+    margin-bottom: 18px;
+  }
+
+  h2 {
+    letter-spacing: 0.1rem;
+    font-size: 1.2rem;
+  }
+}
 </style>

+ 96 - 104
components/Logiciels/Artist/Abonnement.vue

@@ -2,58 +2,16 @@
   <AnchoredSection id="subscription">
     <LayoutContainer>
       <v-row class="mt-12 center-90">
-        <v-col cols="4">
-          <LayoutUISubTitle>
-            S'abonner dès maintenant
-          </LayoutUISubTitle>
+        <LayoutUISubTitle> S'abonner dès maintenant </LayoutUISubTitle>
 
-          <div class="profile-circle">
-            <v-img src="/images/logo/logiciels/OT_Artist-BLANC.png" />
-          </div>
-
-          <div class="subscription-info">
-            <p class="mt-3 mb-6">
-              Pour vous abonner au logiciel, téléchargez et remplissez le
-              formulaire avant de nous le transmettre
-            </p>
-            <a
-              href="https://www.opentalent.fr/fileadmin/stockage/commercial/contrats/BDC_Artist_Public-23.pdf"
-              target="_blank"
-              class="download-button"
-              >
-              Télécharger le formulaire d'abonnement
-            </a>
-          </div>
-
-          <div class="subscription-steps">
-            <ol>
-              <li class="mt-6">
-                Téléchargez le formulaire
-              </li>
-              <li>
-                Complétez le formulaire
-              </li>
-              <li>
-                Joignez le règlement par chèque avec le formulaire à <br />
-                <p class="pa-3">
-                  2iOPENService <br />
-                  217 rue Raoul Follereau <br />
-                  74300 CLUSES
-                </p>
-              </li>
-              <li>
-                Après réception de votre formulaire d'adhésion et de votre
-                règlement, nous vous ouvrons le service choisi. Vous recevrez
-                alors un mail avec votre identifiant de connexion, votre mot de
-                passe, ainsi que l'URL de votre site internet.
-              </li>
-            </ol>
-          </div>
+        <v-col v-if="mdAndUp" cols="4" class="col-1">
+          <LogicielsArtistAbonnementToSubscribe />
         </v-col>
 
-        <v-col cols="8">
+        <v-col cols="12" lg="8" class="col-2">
           <h3>
-            Opentalent Artist, <br> la solution que vous attendiez...
+            Opentalent Artist, <br />
+            la solution que vous attendiez...
           </h3>
 
           <p class="solution">
@@ -64,14 +22,22 @@
             vos besoins d'évolution !
           </p>
 
+          <LogicielsArtistAbonnementToSubscribe v-if="mdAndDown" />
+
           <p class="cmf">
-            Adhérents CMF ? <br> Et si on vous disait que vous l’aviez déjà ...
+            Adhérents CMF ? <br />
+            Et si on vous disait que vous l’aviez déjà&nbsp;...
           </p>
 
-          <div class="border-row">
-            <nuxt-link href="https://www.cmf-musique.org/" target="_blank">
+          <div class="adherent-warning">
+            <nuxt-link
+              href="https://www.cmf-musique.org/"
+              target="_blank"
+              class="logo-cmf-link"
+            >
               <v-img
-                src="/images/logiciels/school/cmf_logo_orange.png"
+                src="/images/logos/cmf/Logo_Confederation_Musicale_de_France-CMF_vivre_la_musique_ensemble.jpg"
+                alt="Logo Confédération Musicale de France - CMF"
                 class="logo-cmf"
               />
             </nuxt-link>
@@ -85,6 +51,16 @@
                 Contactez nous ou contactez votre fédération pour obtenir vos
                 codes d'accès.
               </p>
+
+              <div class="d-flex flex-row justify-center my-4">
+                <v-btn
+                  href="https://www.cmf-musique.org/contact/"
+                  target="_blank"
+                  class="btn-contact"
+                >
+                  Obtenir mon code d'accès
+                </v-btn>
+              </div>
             </div>
           </div>
         </v-col>
@@ -94,70 +70,40 @@
 </template>
 
 <script setup>
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
+import { useDisplay } from 'vuetify'
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+
+const { mdAndDown, mdAndUp, lgAndUp } = useDisplay()
 </script>
 
 <style scoped lang="scss">
-.subscription-steps ol {
-  list-style-type: decimal;
-  padding-left: 2rem;
-  color: var(--on-neutral-color);
-  font-size: 16px;
-  font-weight: 300;
-  line-height: 20px;
-  margin-left: 3rem;
-  width: 20rem;
-}
-
-.profile-circle {
-  top: 0.5rem;
-  width: 100px;
-  height: 100px;
-  position: relative;
-  background-color: var(--on-neutral-color);
-  border-radius: 50%;
-  margin-left: 11rem;
-}
-
-.subscription-info {
-  margin-left: 4rem;
-  background: var(--secondary-color);
-  border-radius: 10px;
-  height: 15rem;
-  width: 20rem;
-  padding: 1rem;
-  margin-top: 1rem;
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  color: var(--on-secondary-color);
-  text-align: center;
-  font-size: 1rem;
-  font-weight: 300;
-  line-height: 18px;
-}
-
-.download-button {
-  font-weight: 700;
-  background-color: var(--on-neutral-color);
-  color: var(--neutral-color);
-  padding: 10px 20px;
-  border-radius: 5px;
-  text-decoration: none;
-  display: inline-block;
+@media (max-width: 1240px) {
+  .col-1 {
+    order: 2;
+  }
+  .col-2 {
+    order: 1;
+  }
 }
 
 .solution {
   width: 45rem;
-  text-align: justify
+
+  @media (max-width: 600px) {
+    width: 100%;
+  }
 }
 
 h3 {
-  color: var(--primary-color);
+  color: var(--on-neutral-color);
   margin-bottom: 4rem;
   font-size: 42px;
   font-weight: 600;
   line-height: 42px;
+
+  @media (max-width: 600px) {
+    font-size: 32px;
+  }
 }
 
 .cmf-container {
@@ -165,12 +111,22 @@ h3 {
   margin-bottom: 4rem;
 
   p {
-    color: var(--on-primary-color);
+    color: var(--on-neutral-color);
     width: 25rem;
     font-weight: 300;
     font-size: 16px;
     line-height: 20px;
     margin-left: 2rem;
+
+    @media (max-width: 1240px) {
+      margin-left: auto;
+      margin-right: auto;
+      width: 90%;
+    }
+  }
+
+  @media (max-width: 1240px) {
+    margin-top: 1rem;
   }
 }
 
@@ -181,15 +137,51 @@ h3 {
   background-size: contain;
   width: 15rem;
   height: 10rem;
+
+  @media (max-width: 1240px) {
+    margin-left: auto;
+    margin-right: auto;
+    width: 90%;
+  }
 }
 
 .cmf {
   margin-top: 3rem;
   margin-bottom: 2rem;
-  color: var(--primary-color);
+  color: var(--on-neutral-color);
   width: 40rem;
   font-size: 34px;
   font-weight: 400;
   line-height: 38px;
+
+  @media (max-width: 600px) {
+    width: 100%;
+  }
+}
+
+.adherent-warning {
+  display: flex;
+  flex-direction: row;
+
+  .logo-cmf-link {
+    margin-top: auto;
+    margin-bottom: auto;
+    padding: 0 16px;
+    border-right: solid 2px var(--on-neutral-color-extra-light);
+  }
+
+  @media (max-width: 600px) {
+    flex-direction: column;
+  }
+}
+
+.btn-contact {
+  height: 53px;
+  background: var(--secondary-color);
+  border-radius: 6px;
+  color: var(--on-secondary-color);
+  padding: 19px 28px;
+  gap: 9px;
+  max-width: 90%;
 }
 </style>

+ 117 - 0
components/Logiciels/Artist/Abonnement/ToSubscribe.vue

@@ -0,0 +1,117 @@
+<template>
+  <div class="profile-circle">
+    <v-img
+      src="/images/logos/opentalent/Logo_Opentalent_Artist-blanc-col.png"
+      alt="Logo Opentalent Artist - logiciel de gestion et de communication pour les orchestres, les chorales, les compagnies artistiques et troupes"
+    />
+  </div>
+
+  <div class="subscription-info">
+    <p class="mt-3 mb-6">
+      Pour vous abonner au logiciel, téléchargez et remplissez le formulaire
+      avant de nous le transmettre
+    </p>
+    <a
+      href="/files/Bon_De_Commande_Artist_Public-2024.pdf"
+      target="_blank"
+      class="download-button"
+    >
+      Télécharger le formulaire d'abonnement
+    </a>
+  </div>
+
+  <div class="subscription-steps">
+    <ol>
+      <li class="mt-6">Téléchargez et complétez le formulaire</li>
+      <li>
+        Réglez votre abonnement par virement ou par chèque
+      </li>
+      <li>
+        Après réception de votre formulaire d'adhésion et de votre règlement,
+        nous vous ouvrons le service choisi. Vous recevrez alors un mail avec
+        votre identifiant de connexion, votre mot de passe, ainsi que l'URL de
+        votre site internet.
+      </li>
+    </ol>
+  </div>
+</template>
+
+<script setup lang="ts"></script>
+
+<style scoped lang="scss">
+.profile-circle {
+  top: 3rem;
+  width: 100px;
+  height: 100px;
+  position: relative;
+  background-color: var(--on-neutral-color);
+  border-radius: 50%;
+  margin-left: 11rem;
+  padding-top: 12px;
+
+  @media (max-width: 1240px) {
+    margin-left: auto;
+    margin-right: auto;
+  }
+}
+
+.subscription-info {
+  margin-left: 4rem;
+  background: var(--secondary-color);
+  border-radius: 10px;
+  height: 15rem;
+  width: 20rem;
+  padding: 1rem;
+  margin-top: 1rem;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  color: var(--on-secondary-color);
+  text-align: center;
+  font-size: 1rem;
+  font-weight: 300;
+  line-height: 18px;
+
+  @media (max-width: 1240px) {
+    width: 80%;
+  }
+
+  @media (max-width: 600px) {
+    width: 100%;
+    margin-left: auto;
+    margin-right: auto;
+  }
+}
+
+.download-button {
+  font-weight: 700;
+  background-color: var(--on-neutral-color);
+  color: var(--neutral-color);
+  padding: 10px 20px;
+  border-radius: 5px;
+  text-decoration: none;
+  display: inline-block;
+  text-align: center;
+}
+
+.subscription-steps ol {
+  list-style-type: decimal;
+  padding-left: 2rem;
+  color: var(--on-neutral-color);
+  font-size: 16px;
+  font-weight: 300;
+  line-height: 20px;
+  margin-left: 3rem;
+  width: 20rem;
+
+  @media (max-width: 1240px) {
+    width: 80%;
+  }
+
+  @media (max-width: 600px) {
+    width: 100%;
+    margin-left: auto;
+    margin-right: auto;
+  }
+}
+</style>

+ 18 - 14
components/Logiciels/Artist/Avantages.vue

@@ -8,33 +8,37 @@ Section "Avantages" de la page du logiciel Artist
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { Benefit } from "~/types/interface";
+import type { Ref } from 'vue'
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { Benefit } from '~/types/interface'
 
 const benefits: Ref<Array<Benefit>> = ref([
   {
-    title: "Un gain de temps",
-    number: "01",
+    title: 'Un gain de temps',
+    number: '01',
     description:
-      "Centralisez toutes vos informations sur un seul et même outil et ne perdez plus de temps avec des fichiers sur diverses applications.",
-    image: "/images/avantages/school/temps.jpg",
+      'Centralisez toutes vos informations sur un seul et même outil et ne perdez plus de temps avec des fichiers sur diverses applications.',
+    image: '/images/components/avantages/un_gain_de_temps.jpg',
+    alt: 'Main tenant un mini réveil',
     isMemberCMF: true,
   },
   {
-    title: "Une activité structurée",
-    number: "02",
+    title: 'Une activité structurée',
+    number: '02',
     description:
-      "Des espaces dédiés et des outils spécifiques à vos besoins pour une gestion optimisée et une lecture simplifiée.",
-    image: "/images/avantages/school/struture.png",
+      'Des espaces dédiés et des outils spécifiques à vos besoins pour une gestion optimisée et une lecture simplifiée.',
+    image: '/images/components/avantages/une_activite_structuree.png',
+    alt: 'Empilement de cube transparent structuré au-dessus d’un plan de maison',
     isMemberCMF: false,
   },
   {
-    title: "Une gestion collaborative",
-    number: "03",
+    title: 'Une gestion collaborative',
+    number: '03',
     description:
       "Grâce à des comptes dédiés, personnalisés et autonomes, permettez à vos membres de mettre à jour leurs informations et d'interagir dans leur agenda.",
-    image: "/images/avantages/school/collaborative.jpg",
+    image: '/images/components/avantages/une_gestion_collaborative.jpg',
+    alt: 'Mains de plusieurs couleurs posées les unes à côté des autres',
     isMemberCMF: true,
   },
-]);
+])
 </script>

+ 33 - 37
components/Logiciels/Artist/Comparatif.vue

@@ -1,17 +1,13 @@
 <template>
   <AnchoredSection id="comparative">
     <LayoutContainer>
-      <LayoutUISubTitle>
-        Comparatif de nos solutions
-      </LayoutUISubTitle>
+      <LayoutUISubTitle> Comparatif de nos solutions </LayoutUISubTitle>
 
-      <LayoutUITitle>
-        Choisissez la version qui vous convient !
-      </LayoutUITitle>
+      <LayoutUITitle> Choisissez la version qui vous convient ! </LayoutUITitle>
 
       <CommonTableComparatif
-        standardPrice="14€"
-        premiumPrice="18€"
+        standard-price="11€"
+        premium-price="18€"
         :items="comparisonItems"
       />
     </LayoutContainer>
@@ -19,82 +15,82 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { ComparisonItem } from "~/types/interface";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { ComparisonItem } from '~/types/interface'
 
 const comparisonItems: Array<ComparisonItem> = [
   {
-    label: "GESTION DU RÉPERTOIRE",
+    label: 'GESTION DU RÉPERTOIRE',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "AGENDA",
+    label: 'AGENDA',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "GESTION DU PARC MATÉRIEL",
+    label: 'GESTION DU PARC MATÉRIEL',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "COMMUNICATION",
+    label: 'COMMUNICATION',
     includedInStandard: false,
     includedInPremium: true,
   },
   {
-    label: "SMS",
-    includedInStandard: "Option",
-    includedInPremium: "Option",
+    label: 'SMS',
+    includedInStandard: 'Option',
+    includedInPremium: 'Option',
   },
   {
-    label: "NOM DE DOMAINE",
-    includedInStandard: "Option",
-    includedInPremium: "Option",
+    label: 'NOM DE DOMAINE',
+    includedInStandard: 'Option',
+    includedInPremium: 'Option',
   },
   {
-    label: "SITE INTERNET",
+    label: 'SITE INTERNET',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "STATISTIQUES",
+    label: 'STATISTIQUES',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "FONCTIONNALITÉ DU RÉSEAU CMF",
+    label: 'FONCTIONNALITÉ DU RÉSEAU CMF',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "SAUVEGARDE",
+    label: 'SAUVEGARDE',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "EXTRANET UTILISATEURS",
-    includedInStandard: "75 comptes",
-    includedInPremium: "150 comptes",
+    label: 'EXTRANET UTILISATEURS',
+    includedInStandard: '75 comptes',
+    includedInPremium: '150 comptes',
   },
   {
-    label: "ESPACE DE STOCKAGE",
-    includedInStandard: "100 Mo",
-    includedInPremium: "1 Go",
+    label: 'ESPACE DE STOCKAGE',
+    includedInStandard: '100 Mo',
+    includedInPremium: '1 Go',
   },
   {
-    label: "PAGE DU SITE INTERNET",
-    includedInStandard: "Restreint",
-    includedInPremium: "Illimités",
+    label: 'PAGES DU SITE INTERNET',
+    includedInStandard: 'Restreint',
+    includedInPremium: 'Illimité',
   },
-];
+]
 </script>
 
 <style scoped>
-
-.v-container{
+.v-container {
   width: 95%;
   margin-right: auto;
   margin-left: auto;
-}</style>
+}
+</style>

+ 56 - 57
components/Logiciels/Artist/Fonctionnalites.vue

@@ -2,107 +2,106 @@
   <AnchoredSection id="functionalities">
     <div>
       <LayoutContainer>
-        <v-row>
-          <v-col cols="12">
-            <CommonCarouselFonctionnalite
-              :cards="cards"
-            />
-          </v-col>
-        </v-row>
+        <CommonCarouselFonctionnalite :cards="cards" />
       </LayoutContainer>
     </div>
   </AnchoredSection>
 </template>
 
 <script setup lang="ts">
-import "vue3-carousel/dist/carousel.css";
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { Functionality } from "~/types/interface";
+import 'vue3-carousel/dist/carousel.css'
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { Functionality } from '~/types/interface'
 
 const cards: Array<Functionality> = [
   {
-    logo: "/images/logiciels/artist/fonctionnalites/Espaces_dedies.svg",
-    title: "ESPACES DÉDIÉS *",
-    list: [
-      "Administration",
-      "Professeurs",
-      "Élèves / Familles",
-    ],
-    options: ["*Disponible sur tous supports"],
+    logo: '/images/components/fonctionnalites/Icone_espaces_dedies.svg',
+    logoAlt: 'Icône smartphone avec cadenas verrouillé',
+    title: 'ESPACES DÉDIÉS *',
+    list: ['Administrations', 'Membres/Adhérents'],
+    options: ['*Disponible sur tous supports'],
   },
   {
-    logo: "/images/logiciels/artist/fonctionnalites/Repertoire.svg",
-    title: "RÉPERTOIRE",
+    logo: '/images/components/fonctionnalites/Icone_repertoire.svg',
+    logoAlt: 'Icône carnet annuaire',
+    title: 'RÉPERTOIRE',
     list: [
-      "Membres",
-      "Personnel administratif ",
-      "Contacts extérieurs, partenaires & donateurs",
+      'Membres',
+      'Personnel administratif ',
+      'Contacts extérieurs, partenaires & donateurs',
     ],
   },
   {
-    logo: "/images/logiciels/artist/fonctionnalites/Agenda.svg",
-    title: "AGENDA",
+    logo: '/images/components/fonctionnalites/Icone_agenda.svg',
+    logoAlt: 'Icône calendrier',
+    title: 'AGENDA',
     list: [
-      "Création et gestion des événements internes et externes",
-      "Invitation aux événements",
-      "Gestion des présences ",
+      'Création et gestion des événements internes et externes',
+      'Invitation aux événements',
+      'Gestion des présences ',
     ],
   },
   {
-    logo: "/images/logiciels/artist/fonctionnalites/Parc_materiel.svg",
-    title: "PARC MATÉRIEL ",
+    logo: '/images/components/fonctionnalites/Icone_parc_materiel.svg',
+    logoAlt: 'Icône carton avec stylos et cahier à l’intérieur',
+    title: 'PARC MATÉRIEL ',
     list: [
-      "Gestion de votre parc matériel (instruments, costumes, accessoires..)",
-      "Locations et prêts de matériel",
-      "Partage de partitions",
+      'Gestion de votre parc matériel (instruments, costumes, accessoires..)',
+      'Locations et prêts de matériel',
+      'Partage de partitions',
     ],
   },
   {
-    logo: "/images/logiciels/artist/fonctionnalites/Communication.svg",
-    title: "COMMUNICATION *",
+    logo: '/images/components/fonctionnalites/Icone_communication.svg',
+    logoAlt: 'Icône enveloppe, téléphone et bulle SMS',
+    title: 'COMMUNICATION *',
     list: [
-      "Édition et envoi de courriers, de mails ou de SMS**",
-      "Création de modèles de courriers, mails ou SMS **",
-      "Outil de publipostage intégré pour un envoi personnalisé",
+      'Édition et envoi de courriers, de mails ou de SMS**',
+      'Création de modèles de courriers, mails ou SMS **',
+      'Outil de publipostage intégré pour un envoi personnalisé',
     ],
-    options: ["* version Artist Premium ", "** en option"],
+    options: ['* version Artist Premium ', '** en option'],
   },
   {
-    logo: "/images/logiciels/artist/fonctionnalites/Site_internet.svg",
-    title: "SITE INTERNET ",
+    logo: '/images/components/fonctionnalites/Icone_site_internet.svg',
+    logoAlt: 'Icône site internet',
+    title: 'SITE INTERNET ',
     list: [
-      "Gestion intégrée au logiciel",
-      "Mise à jour automatique des membres et événements sur votre site",
-      "Possibilité de personnalisé votre template",
+      'Gestion intégrée au logiciel',
+      'Mise à jour automatique des membres et événements sur votre site',
+      'Possibilité de personnalisé votre template',
     ],
   },
   {
-    logo: "/images/logiciels/artist/fonctionnalites/Statistique.svg",
-    title: "STATISTIQUES",
+    logo: '/images/components/fonctionnalites/Icone_statistiques.svg',
+    logoAlt: 'Icône graphique à barre avec ligne ascendante',
+    title: 'STATISTIQUES',
     list: [
       "Rapport d'activité complet en fonction de vos activités",
       "Personnalisation du rapport d'activité grâce aux différents formats proposés lors du téléchargement",
-      "Export des données du logiciel pour une analyse complète",
+      'Export des données du logiciel pour une analyse complète',
     ],
   },
   {
-    logo: "/images/logiciels/artist/fonctionnalites/CMF-réseau-J.png",
-    title: "RÉSEAU CMF ",
+    logo: '/images/logos/cmf/Icone_CMF_reseau_BLACK.png',
+    logoAlt: 'Icône du logo de la CMF (confédération musicale de France)',
+    title: 'RÉSEAU CMF *',
     list: [
-      "Uniquement dédié aux adhérents CMF",
-      "Accès au répertoire du réseau",
-      "Renouvellement de votre adhésion fédérale",
+      'Accès au répertoire du réseau',
+      'Renouvellement de votre adhésion fédérale',
       "Gestion de l'assurance CMF",
     ],
+    options: ['* uniquement dédié aux adhérents CMF'],
   },
   {
-    logo: "/images/logiciels/artist/fonctionnalites/Promotion.svg",
-    title: "PROMOTION DE VOTRE STRUCTURE & VOS ÉVÉNEMENTS ",
+    logo: '/images/components/fonctionnalites/Icone_promotion.svg',
+    logoAlt: 'Icône mégaphone',
+    title: 'PROMOTION DE VOTRE STRUCTURE & VOS ÉVÉNEMENTS ',
     list: [
-      "Sur votre site internet intégré",
+      'Sur votre site internet intégré',
       "Sur l'agenda de la CMF",
-      "Sur l'Agenda culturel Opentalent ",
+      "Sur l'agenda culturel Opentalent ",
     ],
   },
-];
+]
 </script>

+ 43 - 14
components/Logiciels/Artist/Formations.vue

@@ -4,22 +4,25 @@
       <div class="alt-theme">
         <v-container>
           <v-row class="center-90">
-            <LayoutUISubTitle class="mt-12" >
+            <LayoutUISubTitle class="mt-12">
               Pour aller plus loin
             </LayoutUISubTitle>
           </v-row>
 
-          <v-row class="formation py-12 align-center mb-12" no-gutters>
-            <v-col cols="12" lg="6">
-              <v-img src="/images/logiciels/artist/webinaire.jpg" class="meeting-img" />
+          <v-row class="formation center-90 py-12 align-center mb-12">
+            <v-col cols="12" lg="4">
+              <v-img
+                src="/images/pages/opentalent_artist/formations/Webinaire_Opentalent_Artist.jpg"
+                alt="Ordinateur avec un écran en visioconférence avec plusieurs personnes posé sur une table de salon devant une fenêtre avec des plantes et une tasse posées à côté"
+              />
             </v-col>
 
-            <v-col cols="12" lg="6" md="6" sm="6">
-              <h3 class="ml-6 mr-12">
+            <v-col cols="12" lg="6">
+              <h3>
                 Webinaire - Partez à la découverte du logiciel Opentalent Artist
               </h3>
 
-              <p class="details ml-6 mr-12" >
+              <p class="details">
                 Rejoignez notre webinaire, spécialement conçu pour les
                 professionnels du secteur culturel, orchestres, chorales,
                 compagnies de danse, ainsi que les troupes de théâtre et de
@@ -32,9 +35,7 @@
               </p>
 
               <nuxt-link to="/webinaires">
-                <v-btn class="mt-12 ml-6">
-                  S'inscrire à nos webinaires
-                </v-btn>
+                <v-btn> S'inscrire à nos webinaires </v-btn>
               </nuxt-link>
             </v-col>
           </v-row>
@@ -45,7 +46,7 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
 </script>
 
 <style scoped lang="scss">
@@ -59,11 +60,15 @@ import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
 
 .formation {
   .v-img {
-    width: 600px;
-    height: 500px;
+    width: 500px;
+    height: 440px;
     background-position: center;
     background-size: cover;
     border-radius: 10%;
+
+    @media (max-width: 1240px) {
+      margin: 0 auto;
+    }
   }
 
   :deep(.v-img img) {
@@ -83,7 +88,14 @@ import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
     font-size: 1rem;
     line-height: 1.5rem;
     color: var(--on-primary-color);
-    text-align: justify
+
+    @media (max-width: 1240px) {
+      margin-right: 24px !important;
+    }
+
+    @media (max-width: 600px) {
+      margin-right: auto !important;
+    }
   }
 
   .v-btn {
@@ -96,6 +108,23 @@ import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
     border-color: var(--on-primary-color);
     border-radius: 0.5rem;
     width: 90%;
+    margin: 24px auto;
+  }
+
+  .v-col-12:nth-child(2) {
+    @media (min-width: 1240px) {
+      padding: 24px 64px;
+    }
+    @media (max-width: 1240px) {
+      margin: 24px 5%;
+      max-width: 90%;
+    }
+
+    a {
+      display: flex;
+      width: 100%;
+      text-decoration: none;
+    }
   }
 }
 </style>

+ 19 - 16
components/Logiciels/Artist/Presentation.vue

@@ -4,42 +4,45 @@
       title="Présentation d'Opentalent Artist"
       :features="features"
       :pictos="pictos"
-      logo-src="/images/logo/logiciels/OT_Artist-BLANC.png"
-      pricingAmount="14€"
+      logo-src="/images/logos/opentalent/Logo_Opentalent_Artist-blanc-col.png"
+      logo-alt="Logo Opentalent Artist - logiciel de gestion et de communication pour les orchestres, les chorales, les compagnies artistiques et troupes"
+      pricing-amount="11€"
     />
 
     <CommonContainerVideo
       title="Logiciel OpenTalent Artist"
       quote="Le logiciel de gestion et communication au service de votre passion"
-      image-url="/images/logiciels/school/screen2.png"
     />
   </AnchoredSection>
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { FeaturePicto } from "~/types/interface";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { FeaturePicto } from '~/types/interface'
 
 const features = [
-  "Logiciel de gestion et communication en ligne",
-  "Destiné aux structures culturelles (tout statut juridique)",
-  "Gestion complète (membres, événements, planning, matériel,...)",
-  "Une solution simple d'utilisation, intuitive et collaborative"
+  'Logiciel de gestion et communication en ligne',
+  'Destiné aux structures culturelles (tout statut juridique)',
+  'Gestion complète (membres, événements, planning, matériel,...)',
+  "Une solution simple d'utilisation, intuitive et collaborative",
 ]
 
 const pictos: Array<FeaturePicto> = [
   {
-    src: "/images/logiciels/artist/picto1.png",
-    text: "Logiciel de gestion et communication full web",
+    src: '/images/pages/opentalent_artist/presentation/Logiciel_multi-support.png',
+    text: 'Logiciel de gestion et communication full web',
   },
   {
-    src: "/images/logiciels/artist/picto2.png",
+    src: '/images/pages/opentalent_artist/presentation/Site_internet_integre.png',
     text: "Site web intégré & simple d'usage",
   },
   {
-    src: "/images/logiciels/artist/picto3.png",
-    text: "Boostez votre visibilité & communication",
+    src: '/images/pages/opentalent_artist/presentation/Boostez_votre_visibilite_et_communication.png',
+    text: 'Boostez votre visibilité & communication',
   },
-  { src: "/images/logiciels/artist/picto4.png", text: "Communiquez en réseau" },
-];
+  {
+    src: '/images/pages/opentalent_artist/presentation/Communication_en_reseau.png',
+    text: 'Communiquez en réseau',
+  },
+]
 </script>

+ 8 - 8
components/Logiciels/Artist/Reviews.vue

@@ -11,25 +11,25 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { Review } from "~/types/interface";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { Review } from '~/types/interface'
 
 const cards: Array<Review> = [
   {
     review:
       "L'outil répond à toutes les demandes d'une structure de notre taille et la connexion avec le site internet est très pratique.",
-    name: "Patrice MONTESSUIT",
-    status: "Directeur musical ",
+    name: 'Patrice MONTESSUIT',
+    status: 'Directeur musical ',
     structure: "Orchestre d'Harmonie de Cluses (74)",
   },
   {
     review:
       "C'est un outil de travail très intéressant, complet et intuitif quand on comprend certaines subtilités. Il a très bien évolué aussi bien pour les chorales que les harmonie. Mes remarques ont toujours été prises en compte.",
-    name: "Gérard LEFÈBVRE ",
-    status: "Président",
-    structure: "Le choeur du Brevon (74)",
+    name: 'Gérard LEFÈBVRE ',
+    status: 'Président',
+    structure: 'Le choeur du Brevon (74)',
   },
-];
+]
 </script>
 
 <style scoped lang="scss">

+ 43 - 32
components/Logiciels/Artist/SomeNumbers.vue

@@ -1,56 +1,67 @@
 <template>
   <LayoutContainer>
     <v-row class="custom-row">
-      <LayoutUISubTitle class="mb-12">
-        Quelques chiffres
-      </LayoutUISubTitle>
+      <LayoutUISubTitle class="mb-12"> Quelques chiffres </LayoutUISubTitle>
     </v-row>
 
     <v-container>
       <v-row class="card-container mb-12">
-        <v-col
-          cols="3"
-          class="d-flex justify-center align-center small-padding"
-        >
-          <CommonCardStat
-            number="184 634"
-            text="Utilisateurs"
-          />
+        <v-col lg="3" class="d-flex justify-center align-center small-padding">
+          <CommonCardStat number="184 634" text="Utilisateurs" />
         </v-col>
 
-        <v-col cols="3" class="d-flex justify-center align-center">
-          <CommonCardStat
-            number="3 424"
-            text="Structures"
-          />
+        <v-col lg="3" class="d-flex justify-center align-center">
+          <CommonCardStat number="3 423" text="Structures" />
         </v-col>
 
-        <v-col cols="3" class="d-flex justify-center align-center">
-          <CommonCardStat
-            number="13"
-            text="Années d'expérience"
-          />
+        <v-col lg="3" class="d-flex justify-center align-center">
+          <CommonCardStat number="15" text="Années d'expérience" />
         </v-col>
       </v-row>
     </v-container>
 
-    <CommonCarouselClients :items="items" >
-      <template v-slot:title>
-        Plus de <span class="alt-color">3400 structures</span> nous ont déjà adoptées
+    <CommonCarouselClients :items="items">
+      <template #title>
+        Plus de <span class="alt-color">3400 structures</span> nous ont déjà
+        adoptées
       </template>
     </CommonCarouselClients>
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-const items: Ref<Array<{ src: string }>> = ref([
-  { src: "/images/reviews/artist/review1.jpeg" },
-  { src: "/images/reviews/artist/review2.jpg" },
-  { src: "/images/reviews/artist/review3.jpeg" },
-  { src: "/images/reviews/artist/review4.jpg" },
-  { src: "/images/reviews/artist/review5.png" },
-  { src: "/images/reviews/artist/review6.jpeg" },
-]);
+import type { Ref } from 'vue'
+
+const items: Ref<Array<{ src: string; alt: string }>> = ref([
+  {
+    src: '/images/pages/opentalent_artist/reviews/Logo_Union_Musicale_Sarriannaise.jpeg',
+    alt: 'Logo de l’Union Musicale Sarriannaise',
+  },
+  {
+    src: '/images/pages/opentalent_artist/reviews/Logo_Societe_Musicale_Sully_sur_Loire.jpg',
+    alt: 'Logo de la Société Musicale de Sully sur Loire',
+  },
+  {
+    src: '/images/pages/opentalent_artist/reviews/Logo_Orchestre_d_Harmonie_de_Cluses.jpeg',
+    alt: 'Logo de l’Orchestre d’Harmonie de Cluses',
+  },
+  {
+    src: '/images/pages/opentalent_artist/reviews/Logo_Musique_Municipale_Geispolsheim.jpeg',
+    alt: 'Logo Musique Municipale de Geispolsheim',
+  },
+  {
+    src: '/images/pages/opentalent_artist/reviews/Logo_Harmonie_Municipale_de_Montherme.png',
+    alt: 'Logo de l’Harmonie Municipale de Montherme',
+  },
+  {
+    src: '/images/pages/opentalent_artist/reviews/Logo_Echo_Musical_de_Faye_d_Anjou.jpeg',
+    alt: 'Logo de l’Echo Musical de Faye d’Anjou',
+  },
+  {
+    src: '/images/pages/opentalent_artist/reviews/Logo_Union_Musicale_Wattrelosienne.jpg',
+    alt: 'Logo de l’Union Musicale Wattrelosienne',
+  },
+])
 </script>
 
 <style scoped lang="scss">

+ 36 - 29
components/Logiciels/Manager/Avantages.vue

@@ -1,5 +1,3 @@
-
-
 <template>
   <AnchoredSection id="benefits">
     <CommonAvantages
@@ -10,53 +8,62 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { Benefit } from "~/types/interface";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { Benefit } from '~/types/interface'
 
 const benefits: Array<Benefit> = [
   {
-    title: "Sur-mesure",
-    number: "01",
+    title: 'Sur-mesure',
+    number: '01',
     description:
-      "S'adapte à tous les réseaux de type pyramidal, quelque soit le nombre de niveaux :",
-    list: ["Fédérations", "Institutions publiques"],
-    image: "/images/avantages/manager/Sur-mesure.jpg",
+      "S'adapte à tous les réseaux de type pyramidal, quelque soit le nombre de niveaux : fédérations, institutions publiques...",
+    image:
+      '/images/pages/opentalent_manager/avantages/Un_logiciel_sur-mesure.jpg',
+    alt: 'Mètre ruban de couture',
   },
   {
-    title: "Adapté",
-    number: "02",
+    title: 'Adapté',
+    number: '02',
     description:
-      "Chaque structure du réseau dispose de sa propre solution indépendante et connectée au réseau :",
-    list: ["Opentalent manager", "Opentalent school", "Opentalent artist"],
-    image: "/images/avantages/manager/Adapte.jpg",
+      'Chaque structure du réseau dispose de sa propre solution indépendante et connectée au réseau : Opentalent manager, Opentalent school, Opentalent artist',
+    image:
+      '/images/pages/opentalent_manager/avantages/Un_logiciel_adapte_a_chaque_reseau.jpg',
+    alt: 'Réseaux structurés différemment ayant un lien part un atome commun',
   },
   {
-    title: "Économique",
-    number: "03",
+    title: 'Économique',
+    number: '03',
     description:
-      "Une solution éprouvée au niveau national, sans avoir à supporter de coûts de développement importants pour ce type de logiciel.",
-    image: "/images/avantages/manager/Economique.jpg",
+      'Une solution éprouvée au niveau national, sans avoir à supporter de coûts de développement importants pour ce type de logiciel.',
+    image: '/images/pages/opentalent_manager/avantages/Un_outil_economique.jpg',
+    alt: 'Main mettant une pièce dans un cochon tirelire',
   },
   {
-    title: "De pilotage",
-    number: "04",
+    title: 'De pilotage',
+    number: '04',
     description:
       "Pilotez votre réseau de manière quotidienne et en temps réel. Gagnez du temps avec notre solution qui génère automatiquement un rapport d'activité complet.",
-    image: "/images/avantages/manager/Pilotage.jpg",
+    image:
+      '/images/pages/opentalent_manager/avantages/Un_pilotage_des_structures_simple.jpg',
+    alt: 'Commandant de bord posant en uniforme',
   },
   {
-    title: "En réseau",
-    number: "05",
+    title: 'En réseau',
+    number: '05',
     description:
-      "Mise à jour automatique des coordonnées publiques entre les membres du réseau.",
-    image: "/images/avantages/manager/En-reseau.jpg",
+      'Mise à jour automatique des coordonnées publiques entre les membres du réseau.',
+    image:
+      '/images/pages/opentalent_manager/avantages/Un_logiciel_adapte_a_chaque_reseau.jpg',
+    alt: 'Multi-réseau',
   },
   {
-    title: "Confidentiel",
-    number: "06",
+    title: 'Confidentiel',
+    number: '06',
     description:
       "Chaque structure garde son indépendance et reste entièrement maître des informations et des données qu'elle saisit.",
-    image: "/images/avantages/manager/Confidentiel-les-donnees-appartiennent-aux-structures.jpg",
+    image:
+      '/images/pages/opentalent_manager/avantages/Confidentialite_des_donnees_et_independance.jpg',
+    alt: 'Jeune femme ayant le doigt devant la bouche pour instaurer le silence',
   },
-];
+]
 </script>

+ 67 - 51
components/Logiciels/Manager/Fonctionnalites.vue

@@ -4,9 +4,7 @@
       <LayoutContainer>
         <v-row>
           <v-col cols="12">
-            <CommonCarouselFonctionnalite
-              :cards="cards"
-            />
+            <CommonCarouselFonctionnalite :cards="cards" />
           </v-col>
         </v-row>
       </LayoutContainer>
@@ -15,91 +13,109 @@
 </template>
 
 <script setup lang="ts">
-import "vue3-carousel/dist/carousel.css";
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { Functionality } from "~/types/interface";
+import 'vue3-carousel/dist/carousel.css'
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { Functionality } from '~/types/interface'
 
 const cards: Array<Functionality> = [
   {
-    logo:"images/logiciels/manager/fonctionnalites/Espaces_dedies.svg",
-    title: "ESPACES DÉDIÉS *",
-    list: ["Administration","Membres / Adhérents"],
-    options: ["*Disponible sur tous supports "],
+    logo: '/images/components/fonctionnalites/Icone_espaces_dedies.svg',
+    logoAlt: 'Icône smartphone avec cadenas verrouillé',
+    title: 'ESPACES DÉDIÉS *',
+    list: ['Administration', 'Membres / Adhérents'],
+    options: ['*Disponible sur tous supports '],
   },
   {
-    logo: "images/logiciels/manager/fonctionnalites/Repertoire.svg",
-
-    title: "RÉPERTOIRE",
+    logo: '/images/components/fonctionnalites/Icone_repertoire.svg',
+    logoAlt: 'Icône carnet annuaire',
+    title: 'RÉPERTOIRE',
     list: [
-      "Membres",
-      "Personnel administratif ",
-      "Contacts extérieurs, partenaires & donateurs",
+      'Membres',
+      'Personnel administratif ',
+      'Contacts extérieurs, partenaires & donateurs',
     ],
   },
   {
-    logo: "images/logiciels/manager/fonctionnalites/Agenda.svg",
-    title: "AGENDA",
+    logo: '/images/components/fonctionnalites/Icone_agenda.svg',
+    logoAlt: 'Icône calendrier',
+    title: 'AGENDA',
     list: [
-      "Création et gestion des événements internes et externes",
-      "Invitation aux événements",
-      "Gestion des présences ",
+      'Création et gestion des événements internes et externes',
+      'Invitation aux événements',
+      'Gestion des présences ',
     ],
   },
   {
-    logo: "images/logiciels/manager/fonctionnalites/Parc_materiel.svg",
-    title: "PARC MATÉRIEL ",
+    logo: '/images/components/fonctionnalites/Icone_parc_materiel.svg',
+    logoAlt: 'Icône carton avec stylos et cahier à l’intérieur',
+    title: 'PARC MATÉRIEL ',
     list: [
-      "Gestion de votre parc matériel (instruments, costumes, accessoires..)",
-      "Locations et prêts de matériel",
-      "Partage de partitions",
+      'Gestion de votre parc matériel (instruments, costumes, accessoires..)',
+      'Locations et prêts de matériel',
+      'Partage de partitions',
     ],
   },
   {
-    logo: "images/logiciels/manager/fonctionnalites/communication.svg",
-    title: "COMMUNICATION RÉSEAU",
+    logo: '/images/components/fonctionnalites/Icone_communication_en_reseau.svg',
+    logoAlt: 'Icône enveloppe, téléphone et bulle SMS',
+    title: 'COMMUNICATION RÉSEAU',
     list: [
-      "Édition et envoi de courriers, de mails ou de SMS*",
-      "Édition et envoi de newsletter au adhérent du réseau",
-      "Création de modèles de courriers, mails ou SMS",
-      "Outil de publipostage intégré pour un envoi personnalisé",
+      'Édition et envoi de courriers, de mails ou de SMS*',
+      'Édition et envoi de newsletter au adhérent du réseau',
+      'Création de modèles de courriers, mails ou SMS',
+      'Outil de publipostage intégré pour un envoi personnalisé',
     ],
-    options: ["* en option"]
+    options: ['* en option'],
   },
   {
-    logo: "images/logiciels/manager/fonctionnalites/Site_internet.svg",
-    title: "SITE INTERNET ",
+    logo: '/images/components/fonctionnalites/Icone_site_internet.svg',
+    logoAlt: 'Icône site internet',
+    title: 'SITE INTERNET ',
     list: [
-      "Gestion intégrée au logiciel",
-      "Mise à jour automatique des membres et événements sur votre site",
-      "Possibilité de personnalisé votre template",
+      'Gestion intégrée au logiciel',
+      'Mise à jour automatique des membres et événements sur votre site',
+      'Possibilité de personnalisé votre template',
     ],
   },
   {
-    logo: "images/logiciels/manager/fonctionnalites/Statistiques.svg",
-    title: "STATISTIQUES",
+    logo: '/images/components/fonctionnalites/Icone_statistiques.svg',
+    logoAlt: 'Icône graphique à barre avec ligne ascendante',
+    title: 'STATISTIQUES',
     list: [
       "Rapport d'activité complet en fonction de vos activités",
       "Personnalisation du rapport d'activité grâce aux différents formats proposés lors du téléchargement",
-      "Export des données du logiciel pour une analyse complète",
+      'Export des données du logiciel pour une analyse complète',
     ],
   },
   {
-    logo: "images/logiciels/manager/fonctionnalites/Cotisation.svg",
-    title: "COTISATION CMF ",
+    logo: '/images/components/fonctionnalites/Icone_cotisation.svg',
+    logoAlt: 'Icône d’une main donnant de l’argent à une autre main',
+    title: 'COTISATION CMF ',
     list: [
-      "Paramétrage des cotisations",
-      "Lancement de la campagne",
-      "Gestion des règlement & envoi de justificatif (adhésion/assurance...)",
+      'Paramétrage des cotisations',
+      'Lancement de la campagne',
+      'Gestion des règlement & envoi de justificatif (adhésion/assurance...)',
     ],
   },
   {
-    logo: "images/logiciels/manager/fonctionnalites/Fonctionnement_pyramidal.svg",
-    title: "FONCTIONNEMENT PYRAMIDAL ",
+    logo: '/images/components/fonctionnalites/Icone_fonctionnement_pyramidal.svg',
+    logoAlt: 'Icône graphique pyramidale',
+    title: 'FONCTIONNEMENT PYRAMIDAL ',
     list: [
-      "Mise en relation des logiciels (Artist, School et Manager)",
+      'Mise en relation des logiciels (Artist, School et Manager)',
       "Mise en place d'un système d'adhésion",
-      "Communication en réseau",
+      'Communication en réseau',
+    ],
+  },
+  {
+    logo: '/images/components/fonctionnalites/Icone_agenda.svg',
+    logoAlt: 'Icône graphique pyramidale',
+    title: "PROMOTION DU RÉSEAU SUR L'AGENDA CULTUREL",
+    list: [
+      'Publication des événements des structures de votre réseau',
+      "Référencement des structures de votre réseau sur l'annuaire",
+      'Diffusion des annonces du réseau et des structures de votre réseau',
     ],
   },
-];
+]
 </script>

+ 38 - 32
components/Logiciels/Manager/Formation.vue

@@ -3,20 +3,17 @@
     <LayoutContainer>
       <div class="alt-theme pt-6 mt-12">
         <v-row>
-          <LayoutUISubTitle class="mb-6 mt-6">
+          <LayoutUISubTitle class="center-90">
             Nos accompagnements pour aller plus loin
           </LayoutUISubTitle>
         </v-row>
 
-        <v-row class="formation pb-6 align-center">
-          <v-col
-            cols="6"
-            v-for="(formation, index) in formations"
-            :key="index"
-          >
+        <v-row class="formation pb-6 align-center center-90">
+          <v-col v-for="(formation, index) in formations" :key="index" md="6">
             <div class="mb-6">
               <v-img
                 :src="formation.image"
+                :alt="formation.alt"
                 class="background-img"
               />
             </div>
@@ -45,33 +42,35 @@
   </AnchoredSection>
 </template>
 
-<script setup>
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
+<script setup lang="ts">
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { Formation } from '~/types/interface.js'
 
-const formations = ref([
+const formations: Array<Formation> = [
   {
-    id: 1,
-    image: "/images/logiciels/school/formation.png",
-    overlayClass: "image-overlay1",
-    sessions: "Formation sur-mesure",
-    title: " Des formations adaptées à votre projet - en ligne",
+    image:
+      '/images/components/formations/Formations_en_ligne_et_presentiel.jpg',
+    alt: 'Formateur dans une salle avec 5 personnes levant la main',
+    overlayClass: 'image-overlay1',
+    sessions: 'Formation sur-mesure',
+    title: ' Des formations adaptées à votre projet - en ligne',
     description:
       "Chaque projet de solution de mise en réseau d'organisation nécessite un accompagnement sur-mesure par notre équipe de formation en fonction de vos besoins.",
-    buttonText: "Formation sur-mesure",
-    link: "/nous-contacter",
+    buttonText: 'Formation sur-mesure',
+    link: '/nous-contacter',
   },
   {
-    id: 2,
-    image: "/images/logiciels/school/webinaire.png",
-    overlayClass: "image-overlay2",
-    sessions: "Webinaire CMF Réseau",
+    image: '/images/components/formations/Webinaires_visioconferences.jpg',
+    alt: 'Femme sur son bureau avec devant deux écrans d’ordinateur de bureau en visioconférence devant 12 personnes',
+    overlayClass: 'image-overlay2',
+    sessions: 'Webinaire CMF Réseau',
     title: "Trouvez le webinaire qu'il vous faut ",
     description:
       "Des explications précises sur certains modules du logiciel Opentalent Manager, c'est possible pour aller encore plus loin... ",
-    buttonText: "Découvrir nos webinaires ",
-    link: "/webinaires",
+    buttonText: 'Découvrir nos webinaires ',
+    link: '/webinaires',
   },
-]);
+]
 </script>
 
 <style scoped>
@@ -80,8 +79,10 @@ const formations = ref([
   margin: 0 auto;
 }
 
-:deep(h2) {
-  width: 60rem;
+@media (min-width: 600px) {
+  :deep(h2) {
+    width: 60rem;
+  }
 }
 
 .background-img {
@@ -89,14 +90,18 @@ const formations = ref([
   height: 400px;
   background-size: cover;
   background-position: center;
+
+  @media (max-width: 600px) {
+    height: auto;
+  }
 }
 
 .formation {
   .v-btn {
-    width: 30rem;
-    height: 4rem;
+    width: 26rem;
+    height: 44px;
     font-weight: 500;
-    font-size: 1.5rem;
+    font-size: 18px;
     line-height: 18px;
     background: transparent;
     color: var(--on-primary-color);
@@ -108,10 +113,10 @@ const formations = ref([
 
   h3 {
     font-weight: 500;
-    font-size: 1.8rem;
+    font-size: 1.4rem;
     line-height: 26px;
-    color: var(--on-primary-color);
-    margin-bottom: 3rem;
+    color: #caf5f4 !important;
+    margin-bottom: 1.5rem;
   }
 
   h4 {
@@ -125,6 +130,7 @@ const formations = ref([
   .details {
     font-weight: 300;
     font-size: 1.2rem;
+    max-width: 650px;
     line-height: 1.5rem;
     color: var(--on-primary-color);
   }

+ 8 - 7
components/Logiciels/Manager/Network.vue

@@ -1,10 +1,8 @@
 <template>
   <AnchoredSection id="network">
     <LayoutContainer>
-      <v-row class="mt-12  center-90">
-        <LayoutUISubTitle>
-          Un réseau pyramidal
-        </LayoutUISubTitle>
+      <v-row class="mt-12 center-90">
+        <LayoutUISubTitle> Un réseau pyramidal </LayoutUISubTitle>
       </v-row>
 
       <v-row class="center-90">
@@ -14,13 +12,15 @@
           </LayoutUITitle>
 
           <p class="pyramide-details ml-3 mt-6">
-            Notre système s'adapte à toutes les structures de réseau pyramidal, quel que soit le nombre de niveau.
+            Notre système s'adapte à toutes les structures de réseau pyramidal,
+            quel que soit le nombre de niveau.
           </p>
         </v-col>
 
         <v-col cols="12" lg="6" md="6">
           <v-img
-            src="/images/logiciels/manager/reseau.png"
+            src="/images/pages/opentalent_manager/network/Reseau_pyramidale_Opentalent_Manager.png"
+            alt="Graphique réseau pyramidal de la CMF avec les fédérations, les écoles artistique et les structures pratiquantes"
             class="schema-manager"
           />
         </v-col>
@@ -30,7 +30,7 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
 </script>
 
 <style scoped lang="scss">
@@ -45,5 +45,6 @@ import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
   font-weight: 400;
   line-height: 2.375rem;
   width: 40rem;
+  max-width: 90%;
 }
 </style>

+ 17 - 18
components/Logiciels/Manager/Presentation.vue

@@ -7,7 +7,7 @@
           section1title="La solution de mise en réseau des organisations culturelles"
           :features="features"
           :pictos="pictos"
-          logo-src="/images/logo/logiciels/OT_Manager-BLANC.png"
+          logo-src="/images/logos/opentalent/Logo_Opentalent_Manager-blanc-col.png"
           pricing-alt-text="Sur devis"
           pricing-announcement-text=""
           pricing-from-text=""
@@ -18,47 +18,46 @@
       <CommonContainerVideo
         title="Logiciel OpenTalent Manager"
         quote="Une solution unique, collaborative et innovante pour une gestion optimale de votre réseau culturel"
-        image-url="/images/logiciels/school/screen2.png"
       />
     </LayoutContainer>
   </AnchoredSection>
 </template>
 
 <script setup lang="ts">
-import type { FeaturePicto } from "~/types/interface";
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
+import type { FeaturePicto } from '~/types/interface'
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
 
 const features: Array<string> = [
-  "Logiciel de gestion et communication en ligne ",
-  "Répond aux besoins globaux des réseaux culturels ",
-  "Gestion collaborative ",
-  "Mise en valeur des activités des membres du réseau ",
+  'Logiciel de gestion et communication en ligne ',
+  'Répond aux besoins globaux des réseaux culturels ',
+  'Gestion collaborative ',
+  'Mise en valeur des activités des membres du réseau ',
 ]
 
 const pictos: Array<FeaturePicto> = [
   {
-    src: "/images/logiciels/manager/picto1.png",
-    text: "Logiciel de gestion et communication full web",
+    src: '/images/pages/opentalent_manager/presentation/picto1.png',
+    text: 'Logiciel de gestion et communication full web',
   },
   {
-    src: "/images/logiciels/manager/picto2.png",
+    src: '/images/pages/opentalent_manager/presentation/picto2.png',
     text: "Site web intégré & simple d'usage",
   },
   {
-    src: "/images/logiciels/manager/picto3.png",
-    text: "Boostez votre visibilité & communication",
+    src: '/images/pages/opentalent_manager/presentation/picto3.png',
+    text: 'Boostez votre visibilité & communication',
   },
   {
-    src: "/images/logiciels/manager/picto4.png",
-    text: "Communiquez en réseau",
+    src: '/images/pages/opentalent_manager/presentation/picto4.png',
+    text: 'Communiquez en réseau',
   },
   // {
   //   src: "/images/logiciels/manager/picto5.png",
   //   text: "Sur-mesure",
   // },
   {
-    src: "/images/logiciels/manager/picto6.png",
-    text: "Pout tout type de réseau pyramidal",
+    src: '/images/pages/opentalent_manager/presentation/picto6.png',
+    text: 'Pout tout type de réseau pyramidal',
   },
-];
+]
 </script>

+ 22 - 31
components/Logiciels/Manager/Reviews.vue

@@ -11,50 +11,41 @@
 </template>
 
 <script setup lang="ts">
-
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { Review } from "~/types/interface";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { Review } from '~/types/interface'
 
 const cards: Array<Review> = [
   {
     review:
       "L'outil répond à toutes les demandes d'une structure de notre taille et la connexion avec le site internet est très pratique.",
-    name: "Christophe MORIZOT",
-    status: "Président ",
-    structure: "Confédération Musicale de France (92)",
-  },
-  {
-    review:
-      "Lorem ipsum dolor sit amet consectetur adipisicing elit.Provident porro fuga incidunt quae, doloremque tenetur aliquam  exercitationem deleniti aspernatur illo rem deserunt sapiente empore dolorem ipsa aliquid vel nihil eius.",
-    name: "Eric TAUVRON ",
-    status: "Vice-président",
-    structure: "CMF Rhône - Grand Lyon (69)",
+    name: 'Christophe MORIZOT',
+    status: 'Président ',
+    structure: 'Confédération Musicale de France (92)',
   },
+  // {
+  //   review:
+  //     'Lorem ipsum dolor sit amet consectetur adipisicing elit.Provident porro fuga incidunt quae, doloremque tenetur aliquam  exercitationem deleniti aspernatur illo rem deserunt sapiente empore dolorem ipsa aliquid vel nihil eius.',
+  //   name: 'Eric TAUVRON ',
+  //   status: 'Vice-président',
+  //   structure: 'CMF Rhône - Grand Lyon (69)',
+  // },
   {
     review:
       "C'est un outil de travail très intéressant, complet et intuitif quand on comprend certaines subtilités. Il a très bien évolué aussi bien pour les chorales que les harmonie. Mes remarques ont toujours été prises en compte.",
-    name: "Noëlle ROBERT",
-    status: "Président",
+    name: 'Noëlle ROBERT',
+    status: 'Président',
     structure: "CMF Côte d'or (21)",
   },
-  {
-    review:
-      "Lorem ipsum dolor sit amet consectetur adipisicing elit.Provident porro fuga incidunt quae, doloremque tenetur aliquam  exercitationem deleniti aspernatur illo rem deserunt sapiente empore dolorem ipsa aliquid vel nihil eius.",
-    name: "Laurent Lebon",
-    status: "Chef d'orchestre",
-    structure: "Conservatoire de Lyon",
-  },
-  {
-    review:
-      "Lorem ipsum dolor sit amet consectetur adipisicing elit.Provident porro fuga incidunt quae, doloremque tenetur aliquam  exercitationem deleniti aspernatur illo rem deserunt sapiente empore dolorem ipsa aliquid vel nihil eius.",
-    name: "Laurent Lebon",
-    status: "Chef d'orchestre",
-    structure: "Conservatoire de Lyon",
-  },
-];
+  // {
+  //   review:
+  //     'Lorem ipsum dolor sit amet consectetur adipisicing elit.Provident porro fuga incidunt quae, doloremque tenetur aliquam  exercitationem deleniti aspernatur illo rem deserunt sapiente empore dolorem ipsa aliquid vel nihil eius.',
+  //   name: 'Laurent Lebon',
+  //   status: "Chef d'orchestre",
+  //   structure: 'Conservatoire de Lyon',
+  // },
+]
 </script>
 
-
 <style scoped>
 .v-container {
   padding: 0 !important;

+ 9 - 25
components/Logiciels/Manager/SomeNumbers.vue

@@ -1,33 +1,19 @@
 <template>
   <LayoutContainer>
     <v-row class="align-center">
-      <LayoutUISubTitle>
-        Quelques chiffres
-      </LayoutUISubTitle>
+      <LayoutUISubTitle> Quelques chiffres </LayoutUISubTitle>
     </v-row>
 
     <v-container>
       <v-row class="card-container justify-center mb-12">
-        <v-col
-          cols="3"
-          class="d-flex justify-center align-center small-padding"
-        >
-          <CommonCardStat
-            number="140"
-            text="Structures en réseau"
-          />
+        <v-col md="3" class="d-flex justify-center align-center small-padding">
+          <CommonCardStat number="140" text="Structures en réseau" />
         </v-col>
-        <v-col cols="3" class="d-flex justify-center align-center">
-          <CommonCardStat
-            number="300 000"
-            text="Utilisateurs"
-          />
+        <v-col md="3" class="d-flex justify-center align-center">
+          <CommonCardStat number="216 498" text="Utilisateurs" />
         </v-col>
-        <v-col cols="3" class="d-flex justify-center align-center">
-          <CommonCardStat
-            number="12"
-            text="Années de collaboration"
-          />
+        <v-col md="3" class="d-flex justify-center align-center">
+          <CommonCardStat number="17" text="Années de collaboration" />
         </v-col>
       </v-row>
     </v-container>
@@ -40,7 +26,7 @@
 
         <nuxt-link href="https://www.cmf-musique.org/" target="_blank">
           <v-img
-            src="/images/logiciels/manager/cmf.jpg"
+            src="/images/logos/cmf/Logo_Confederation_Musicale_de_France-CMF_vivre_la_musique_ensemble.jpg"
             class="cmf-img mb-6"
           />
         </nuxt-link>
@@ -49,9 +35,7 @@
   </LayoutContainer>
 </template>
 
-<script setup lang="ts">
-
-</script>
+<script setup lang="ts"></script>
 
 <style scoped lang="scss">
 .custom-row {

+ 16 - 10
components/Logiciels/School/Avantages.vue

@@ -8,32 +8,38 @@ Section "Avantages" de la page du logiciel School
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { Benefit } from "~/types/interface";
+import type { Ref } from 'vue'
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { Benefit } from '~/types/interface'
 
 // Exemple de données pour les cartes
 const benefits: Ref<Array<Benefit>> = ref([
   {
     title: 'Un gain de temps',
     number: '01',
-    description: 'Centralisez toutes vos informations sur un seul et même outil et ne perdez plus de temps avec des fichiers sur diverses applications.',
-    image: '/images/avantages/school/temps.jpg',
+    description:
+      'Centralisez toutes vos informations sur un seul et même outil et ne perdez plus de temps avec des fichiers sur diverses applications.',
+    image: '/images/components/avantages/un_gain_de_temps.jpg',
+    alt: '',
     isMemberCMF: true,
   },
   {
     title: 'Une activité structurée',
     number: '02',
-    description: 'Des espaces dédiés et des outils spécifiques à vos besoins pour une gestion optimisée et une lecture simplifiée.',
-    image: '/images/avantages/school/struture.png',
+    description:
+      'Des espaces dédiés et des outils spécifiques à vos besoins pour une gestion optimisée et une lecture simplifiée.',
+    image: '/images/components/avantages/une_activite_structuree.png',
+    alt: '',
     isMemberCMF: false,
   },
   {
     title: 'Une gestion collaborative',
     number: '03',
-    description: 'Grâce à des comptes dédiés, personnalisés et autonomes, permettez à vos membres de mettre à jour leurs informations et d\'interagir dans leur agenda.',
-    image: '/images/avantages/school/collaborative.jpg',
+    description:
+      "Grâce à des comptes dédiés, personnalisés et autonomes, permettez à vos membres de mettre à jour leurs informations et d'interagir dans leur agenda.",
+    image: '/images/components/avantages/une_gestion_collaborative.jpg',
+    alt: '',
     isMemberCMF: true,
   },
-]);
-
+])
 </script>

+ 45 - 51
components/Logiciels/School/Comparatif.vue

@@ -1,119 +1,113 @@
 <template>
   <AnchoredSection id="comparative">
     <LayoutContainer>
-      <LayoutUISubTitle>
-        Comparatif de nos solutions
-      </LayoutUISubTitle>
+      <v-row class="center-90">
+        <LayoutUISubTitle> Comparatif de nos solutions </LayoutUISubTitle>
 
-      <LayoutUITitle>
-        Choisissez la version qui vous convient !
-      </LayoutUITitle>
+        <LayoutUITitle>
+          Choisissez la version qui vous convient !
+        </LayoutUITitle>
 
-      <CommonTableComparatif
-        standardPrice="32,90€"
-        premiumPrice="46,20€"
-        :items="comparisonItems"
-      />
+        <CommonTableComparatif
+          standard-price="34,90€"
+          premium-price="49€"
+          :items="comparisonItems"
+        />
+      </v-row>
     </LayoutContainer>
   </AnchoredSection>
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { ComparisonItem } from "~/types/interface";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { ComparisonItem } from '~/types/interface'
 
 const comparisonItems: Array<ComparisonItem> = [
   {
-    label: "GESTION DU RÉPERTOIRE",
+    label: 'GESTION DU RÉPERTOIRE',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "AGENDA",
+    label: 'AGENDA',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "SUIVI PÉDAGOGIQUE",
+    label: 'SUIVI PÉDAGOGIQUE',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "GESTION DU PARC MATÉRIEL",
+    label: 'GESTION DU PARC MATÉRIEL',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "COMMUNICATION",
+    label: 'COMMUNICATION',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "SMS",
-    includedInStandard: "Option",
-    includedInPremium: "Option",
+    label: 'SMS',
+    includedInStandard: 'Option',
+    includedInPremium: 'Option',
   },
   {
-    label: "NOM DE DOMAINE",
-    includedInStandard: "Option",
-    includedInPremium: "Option",
+    label: 'NOM DE DOMAINE',
+    includedInStandard: 'Option',
+    includedInPremium: 'Option',
   },
   {
-    label: "SITE INTERNET",
+    label: 'SITE INTERNET',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "STATISTIQUES",
+    label: 'STATISTIQUES',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "FONCTIONNALITÉ DU RÉSEAU CMF",
+    label: 'FONCTIONNALITÉ DU RÉSEAU CMF',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "SAUVEGARDE",
+    label: 'SAUVEGARDE',
     includedInStandard: true,
     includedInPremium: true,
   },
   {
-    label: "EXTRANET UTILISATEURS",
+    label: 'EXTRANET UTILISATEURS',
     includedInStandard: false,
-    includedInPremium: "Option",
+    includedInPremium: 'Option',
   },
   {
-    label: "PRÉINSCRIPTION EN LIGNE",
+    label: 'PRÉINSCRIPTION EN LIGNE',
     includedInStandard: false,
-    includedInPremium: "Option",
+    includedInPremium: 'Option',
   },
   {
     label: "GRILLES D'ÉVALUATION",
-    includedInStandard: true,
-    includedInPremium: "Option",
+    includedInStandard: 'Option',
+    includedInPremium: 'Option',
   },
   {
-    label: "GESTION DES RÈGLEMENTS",
-    includedInStandard: "Option",
-    includedInPremium: "Option",
+    label: 'GESTION DES RÈGLEMENTS',
+    includedInStandard: 'Option',
+    includedInPremium: 'Option',
   },
   {
-    label: "ESPACE DE STOCKAGE",
-    includedInStandard: "500 Mo",
-    includedInPremium: "1 Go",
+    label: 'ESPACE DE STOCKAGE',
+    includedInStandard: '500 Mo',
+    includedInPremium: '1 Go',
   },
   {
-    label: "PAGE DU SITE INTERNET",
-    includedInStandard: "restreint",
-    includedInPremium: "illimités",
+    label: 'PAGE DU SITE INTERNET',
+    includedInStandard: 'Restreint',
+    includedInPremium: 'Illimité',
   },
-];
+]
 </script>
-<style scoped>
-
-.v-container{
-  width: 95%;
-  margin-right: auto;
-  margin-left: auto;
-}</style>
+<style scoped></style>

+ 0 - 139
components/Logiciels/School/Contact.vue

@@ -1,139 +0,0 @@
-<template>
-  <AnchoredSection id="contact">
-    <LayoutContainer>
-      <!-- Section "Appelez nous" -->
-      <v-row>
-        <v-col cols="6">
-          <v-img
-            src="/images/contact/contact.jpg"
-            class="help-img"
-          />
-        </v-col>
-
-        <v-col cols="5">
-          <LayoutUISubTitle>
-            Contactez-nous
-          </LayoutUISubTitle>
-
-          <LayoutUITitle>
-            Vous avez un projet ?
-          </LayoutUITitle>
-
-          <div class="pl-6">
-            <h6 class="subtitle">
-              N'attendez plus, appelez-nous !
-            </h6>
-            <p class="contact-details">
-              Vous avez une identité, des besoins, des projets... On est là pour
-              vous écouter et vous offrir une offre personnalisée ! Que vous
-              soyez une petite ou une structure plus conséquente, notre offre
-              s'adapte à toutes les tailles : le prix de l’abonnement au
-              logiciel varie en fonction du nombre d'élèves, tout en conservant
-              l'intégralité des fonctionnalités.
-            </p>
-
-            <v-btn to="nous-contacter" class="btn-contact"> Nous contacter </v-btn>
-          </div>
-        </v-col>
-      </v-row>
-
-      <!-- Section "Adhérent CMF" -->
-      <v-row class="center-90" >
-        <v-col cols="6" >
-          <LayoutUISubTitle>
-            Adhérents CMF
-          </LayoutUISubTitle>
-
-          <LayoutUITitle>
-            Bénéficiez de conditions privilégiées
-          </LayoutUITitle>
-
-          <div class="pl-4">
-            <h6 class="subtitle">
-              N'attendez plus, appelez-nous
-            </h6>
-
-            <p class="contact-details mr-12">
-              Si votre établissement d’enseignement artistique est adhérent à la
-              Confédération Musicale de France (CMF), vous bénéficiez
-              gratuitement, dans le cadre de votre adhésion, de la version
-              Opentalent Artist standard et de conditions privilégiées pour la
-              version Opentalent School. <br />
-            </p>
-
-            <p class="mt-6 contact-details">
-              Contactez-nous directement ou contactez votre fédération pour
-              obtenir vos codes d’accès.
-            </p>
-
-            <v-btn
-              href="https://www.cmf-musique.org/contact/"
-              target="_blank"
-              class="btn-contact"
-            >
-              Je souhaite obtenir mon code d'accès
-            </v-btn>
-          </div>
-        </v-col>
-
-        <v-col cols="6">
-           <v-img
-             src="/images/logiciels/school/CMF-vivre_la_musique_ensemble.jpg"
-             class="logo-cmf mt-12"
-           />
-        </v-col>
-      </v-row>
-    </LayoutContainer>
-  </AnchoredSection>
-</template>
-<script setup>
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-</script>
-
-<style scoped>
-.help-img {
-  width: 100%;
-  height: 90%;
-  object-fit: cover;
-  object-position: center;
-}
-
-.logo-cmf {
-  background-repeat: no-repeat;
-  background-size: contain;
-  width: 80%;
-  height: 100%;
-}
-
-.btn-contact {
-  margin-top: 1rem;
-  height: 53px;
-  background: var(--secondary-color);
-  border-radius: 6px;
-  color: var(--on-secondary-color);
-  padding: 19px 28px;
-  gap: 9px;
-}
-
-.subtitle {
-  font-weight: 400;
-  font-size: 34px;
-  line-height: 38px;
-  color: var(--primary-color);
-  margin-bottom: 2rem;
-}
-
-.contact-details {
-  font-weight: 300;
-  font-size: 16px;
-  line-height: 20px;
-  color: var(--primary-color);
-  text-align: justify;
-}
-
-@media (max-width: 1600px) {
-  .contact-details {
-    width: 30rem !important;
-  }
-}
-</style>

+ 77 - 83
components/Logiciels/School/Fonctionnalites.vue

@@ -1,143 +1,137 @@
 <template>
   <AnchoredSection id="functionalities">
-    <div>
-      <LayoutContainer>
-        <v-row>
-          <v-col cols="12">
-            <CommonCarouselFonctionnalite
-              :cards="cards"
-            />
-          </v-col>
-        </v-row>
-      </LayoutContainer>
-    </div>
+    <LayoutContainer>
+      <CommonCarouselFonctionnalite :cards="cards" />
+    </LayoutContainer>
   </AnchoredSection>
 </template>
 
 <script setup lang="ts">
-import "vue3-carousel/dist/carousel.css";
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { Functionality } from "~/types/interface";
+import 'vue3-carousel/dist/carousel.css'
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { Functionality } from '~/types/interface'
 
 const cards: Array<Functionality> = [
   {
-    logo: "/images/logiciels/school/fonctionnalites/Espaces.svg",
-    title: "ESPACES DÉDIÉS *",
-    list: [
-      "Administration",
-      "Professeurs",
-      "Élèves / Familles",
-    ],
-    options: ["*Disponible sur tous supports"],
+    logo: '/images/components/fonctionnalites/Icone_espaces_dedies.svg',
+    logoAlt: 'Icône smartphone avec cadenas verrouillé',
+    title: 'ESPACES DÉDIÉS *',
+    list: ['Administration', 'Professeurs', 'Élèves / Familles'],
+    options: ['* Disponible sur tous supports'],
   },
   {
-    logo: "/images/logiciels/school/fonctionnalites/Répertoire.png",
-
-    title: "RÉPERTOIRE",
+    logo: '/images/components/fonctionnalites/Icone_repertoire.svg',
+    logoAlt: 'Icône carnet annuaire',
+    title: 'RÉPERTOIRE',
     list: [
-      "Élèves et responsable légaux",
-      "Personnel administratif et professeurs",
-      "Contacts extérieurs, partenaires & donateurs",
+      'Élèves et responsable légaux',
+      'Personnel administratif et professeurs',
+      'Contacts extérieurs, partenaires & donateurs',
     ],
   },
   {
-    logo: "/images/logiciels/school/fonctionnalites/Pré-inscription.png",
-    title: "PRÉINSCRIPTION EN LIGNE",
+    logo: '/images/components/fonctionnalites/Icone_preinscription_en_ligne.svg',
+    logoAlt: "Icône d'un fichier devant un écran d'ordinateur",
+    title: 'PRÉINSCRIPTION EN LIGNE *',
     list: [
-      "Paramètrage personnalisé des formulaires & mails automatiques",
-      "Gestion des réinscriptions et des nouvelles inscriptions",
-      "Gestion des quotas et du suivi des préinscriptions en ligne",
+      'Paramétrage personnalisé des formulaires & mails automatiques',
+      'Gestion des réinscriptions et des nouvelles inscriptions',
+      'Gestion des quotas et du suivi des préinscriptions en ligne',
     ],
+    options: ['* en option'],
   },
   {
-    logo: "/images/logiciels/school/fonctionnalites/Agenda.png",
-    title: "AGENDA",
+    logo: '/images/components/fonctionnalites/Icone_agenda.svg',
+    logoAlt: 'Icône calendrier',
+    title: 'AGENDA',
     list: [
-      "Création et gestion des cours, examens, événements et prestations pédagogiques",
-      "Planning interactif avec un contrôle de cohérence",
-      "Gestion des présences et absences",
+      'Création et gestion des cours, examens, événements et prestations pédagogiques',
+      'Planning interactif avec un contrôle de cohérence',
+      'Gestion des présences et absences',
     ],
   },
   {
-    logo: "/images/logiciels/school/fonctionnalites/Parc-matériel.png",
-    title: "PARC MATÉRIEL ",
+    logo: '/images/components/fonctionnalites/Icone_parc_materiel.svg',
+    logoAlt: 'Icône carton avec stylos et cahier à l’intérieur',
+    title: 'PARC MATÉRIEL ',
     list: [
-      "Gestion de votre parc matériel (instruments, costumes, accessoires..)",
-      "Planning interactif avec un contrôle de cohérence",
-      "Gestion des présences et absences",
+      'Gestion de votre parc matériel (instruments, costumes, accessoires..)',
+      'Planning interactif avec un contrôle de cohérence',
+      'Gestion des présences et absences',
     ],
   },
   {
-    logo: "/images/logiciels/school/fonctionnalites/Suivi-pédagogique.png",
-
-    title: "SUIVI PÉDAGOGIQUE",
+    logo: '/images/components/fonctionnalites/Icone_suivi_pedagogique.svg',
+    logoAlt: 'Chapeau de diplômé américain',
+    title: 'SUIVI PÉDAGOGIQUE',
     list: [
-      "Gestion du cursus pédagogique (critères personnalisables)",
-      "Création des examens et envoi des convocations",
-      "Édition des bulletins de notes",
+      'Gestion du cursus pédagogique (critères personnalisables)',
+      'Création des examens et envoi des convocations',
+      'Édition des bulletins de notes',
     ],
   },
   {
-    logo: "/images/logiciels/school/fonctionnalites/Facture.png",
-
-    title: "FACTURATION",
+    logo: '/images/components/fonctionnalites/Icone_facturation_et_reglement.svg',
+    logoAlt:
+      "Fichier arborant un symbole monétaire devant un écran d'ordinateur",
+    title: 'FACTURATION',
     list: [
-      "Facturation automatisée selon différents critères",
-      "Suivi des règlements et gestion des relances",
-      "En option : de nombreux moyens de paiement",
+      'Facturation automatisée selon différents critères',
+      'Suivi des règlements et gestion des relances',
+      'En option : de nombreux moyens de paiement',
     ],
   },
   {
-    logo: "/images/logiciels/school/fonctionnalites/Communication.png",
-
-    title: "COMMUNICATION",
+    logo: '/images/components/fonctionnalites/Icone_communication.svg',
+    logoAlt: 'Icône enveloppe, téléphone et bulle SMS',
+    title: 'COMMUNICATION',
     list: [
-      "Édition et envoi de courriers, de mails ou de SMS*",
-      "Création de modèles de courriers, mails ou SMS",
-      "Outil de publipostage intégré pour un envoi personnalisé",
+      'Édition et envoi de courriers, de mails ou de SMS*',
+      'Création de modèles de courriers, mails ou SMS',
+      'Outil de publipostage intégré pour un envoi personnalisé',
     ],
-    options: ["* en option"],
+    options: ['* en option'],
   },
   {
-    logo: "/images/logiciels/school/fonctionnalites/internet.png",
-
-    title: "SITE INTERNET ",
+    logo: '/images/components/fonctionnalites/Icone_site_internet.svg',
+    logoAlt: 'Icône site internet',
+    title: 'SITE INTERNET ',
     list: [
-      "Gestion intégrée au logiciel",
-      "Mise à jour automatique des membres et événements sur votre site",
-      "Possibilité de personnalisé votre template",
+      'Gestion intégrée au logiciel',
+      'Mise à jour automatique des membres et événements sur votre site',
+      'Possibilité de personnalisé votre template',
     ],
   },
   {
-    logo: "/images/logiciels/school/fonctionnalites/Statistiques.png",
-
-    title: "STATISTIQUES",
+    logo: '/images/components/fonctionnalites/Icone_statistiques.svg',
+    logoAlt: 'Icône graphique à barre avec ligne ascendante',
+    title: 'STATISTIQUES',
     list: [
       "Rapport d'activité complet en fonction de vos activités",
       "Personnalisation du rapport d'activité grâce aux différents formats proposés lors du téléchargement",
-      "Export des données du logiciel pour une analyse complète",
+      'Export des données du logiciel pour une analyse complète',
     ],
   },
   {
-    logo: "/images/logiciels/school/fonctionnalites/Agenda.png",
-
-    title: "RÉSEAU CMF *",
+    logo: '/images/logos/cmf/Icone_CMF_reseau_BLACK.png',
+    logoAlt: 'Logo CMF',
+    title: 'RÉSEAU CMF *',
     list: [
-      "Accès au répertoire du réseau",
-      "Renouvellement de votre adhésion fédérale",
+      'Accès au répertoire du réseau',
+      'Renouvellement de votre adhésion fédérale',
       "Gestion de l'assurance CMF",
     ],
-    options: ["* Uniquement dédié au adhérents CMF"],
+    options: ['* Uniquement dédié au adhérents CMF'],
   },
   {
-    logo: "/images/logiciels/school/fonctionnalites/Promotion.png",
-
-    title: "PROMOTION DE VOTRE STRUCTURE & VOS ÉVÉNEMENTS ",
+    logo: '/images/components/fonctionnalites/Icone_promotion.svg',
+    logoAlt: 'Icône mégaphone',
+    title: 'PROMOTION DE VOTRE STRUCTURE & VOS ÉVÉNEMENTS ',
     list: [
-      "Sur votre site internet intégré",
+      'Sur votre site internet intégré',
       "Sur l'agenda de la CMF",
       "Sur l'agenda culturel Opentalent",
     ],
   },
-];
+]
 </script>

+ 64 - 32
components/Logiciels/School/Formations.vue

@@ -2,21 +2,21 @@
   <AnchoredSection id="webinars">
     <LayoutContainer>
       <div class="alt-theme pt-6 mt-12">
-        <v-row>
-          <LayoutUISubTitle>
-            Nos accompagnements sur-mesure
-          </LayoutUISubTitle>
+        <v-row class="center-90">
+          <LayoutUISubTitle> Nos accompagnements sur-mesure </LayoutUISubTitle>
         </v-row>
 
-        <v-row class="formation pb-6 align-center">
+        <v-row class="formation pb-6 align-center center-90">
           <v-col
-            cols="6"
             v-for="(formation, index) in formations"
             :key="index"
+            cols="12"
+            md="6"
           >
             <div class="mb-6">
               <v-img
                 :src="formation.image"
+                :alt="formation.alt"
                 class="background-img"
               />
             </div>
@@ -46,39 +46,37 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { Formation } from "~/types/interface";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { Formation } from '~/types/interface'
 
 const formations: Array<Formation> = [
   {
-    image: "/images/logiciels/school/formation.png",
-    overlayClass: "image-overlay1",
-    sessions: "3 formations disponibles",
-    title: "Des formations adaptées à chacun - en ligne",
+    image:
+      '/images/components/formations/Formations_en_ligne_et_presentiel.jpg',
+    alt: 'Formateur dans une salle avec 5 personnes levant la main',
+    overlayClass: 'image-overlay1',
+    sessions: '3 formations disponibles',
+    title: 'Des formations adaptées à chacun - en ligne',
     description:
-      "Parce qu’on sait qu’appréhender un nouvel outil peut-être fastidieux et que vous n’avez pas de temps à perdre,...",
-    buttonText: "Découvrir toutes nos formations",
-    link: "/formations",
+      'Parce qu’on sait qu’appréhender un nouvel outil peut-être fastidieux et que vous n’avez pas de temps à perdre,...',
+    buttonText: 'Découvrir toutes nos formations',
+    link: '/formations',
   },
   {
-    image: "/images/logiciels/school/webinaire.png",
-    overlayClass: "image-overlay2",
-    sessions: "Toutes nos sessions",
+    image: '/images/components/formations/Webinaires_visioconferences.jpg',
+    alt: 'Femme sur son bureau avec devant deux écrans d’ordinateur de bureau en visioconférence devant 12 personnes',
+    overlayClass: 'image-overlay2',
+    sessions: 'Toutes nos sessions',
     title: "Trouvez le webinaire qu'il vous faut ",
     description:
       "Des explications précises sur certains modules du logiciel Opentalent School, c'est possible pour aller encore plus loin...",
-    buttonText: "Découvrir nos webinaires ",
-    link: "/webinaires",
+    buttonText: 'Découvrir nos webinaires ',
+    link: '/webinaires',
   },
-];
+]
 </script>
 
 <style scoped>
-.v-row {
-  max-width: 1600px;
-  margin: 0 auto;
-}
-
 :deep(h2) {
   width: 60rem;
 }
@@ -88,6 +86,10 @@ const formations: Array<Formation> = [
   height: 400px;
   background-size: cover;
   background-position: center;
+
+  @media (max-width: 600px) {
+    height: auto;
+  }
 }
 
 .alt-color {
@@ -96,10 +98,10 @@ const formations: Array<Formation> = [
 
 .formation {
   .v-btn {
-    width: 30rem;
-    height: 4rem;
+    width: 26rem;
+    height: 44px;
     font-weight: 500;
-    font-size: 1.5rem;
+    font-size: 18px;
     line-height: 18px;
     background: transparent;
     color: var(--on-primary-color);
@@ -111,10 +113,10 @@ const formations: Array<Formation> = [
 
   h3 {
     font-weight: 500;
-    font-size: 1.8rem;
+    font-size: 1.4rem;
     line-height: 26px;
-    color: var(--on-primary-color);
-    margin-bottom: 3rem;
+    color: var(--secondary-color) !important;
+    margin-bottom: 1.5rem;
   }
 
   h4 {
@@ -128,8 +130,38 @@ const formations: Array<Formation> = [
   .details {
     font-weight: 300;
     font-size: 1.2rem;
+    max-width: 650px;
     line-height: 1.5rem;
     color: var(--on-primary-color);
   }
+
+  @media (max-width: 1240px) {
+    .background-img,
+    h3,
+    h4,
+    .details {
+      margin-left: auto;
+      margin-right: auto;
+      text-align: center;
+    }
+
+    .v-btn {
+      width: 80%;
+      margin-left: 10%;
+    }
+  }
+
+  @media (max-width: 600px) {
+    .v-btn {
+      height: 96px;
+    }
+
+    :deep(.v-btn__content) {
+      white-space: pre-wrap;
+      line-height: 1.2em;
+      padding: initial;
+      text-align: center;
+    }
+  }
 }
 </style>

+ 14 - 15
components/Logiciels/School/Presentation.vue

@@ -4,45 +4,44 @@
       title="Présentation d'Opentalent School"
       :features="features"
       :pictos="pictos"
-      logo-src="/images/logo/logiciels/OT_School-blanc.png"
+      logo-src="/images/logos/opentalent/Logo_Opentalent_School-blanc-col.png"
       pricing-amount="20€"
     />
 
     <CommonContainerVideo
       title="Logiciel OpenTalent School"
       quote="Pour les petits comme pour les grands établissements d’enseignement artistique"
-      image-url="/images/logiciels/school/screen2.png"
     />
   </AnchoredSection>
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { FeaturePicto } from "~/types/interface";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { FeaturePicto } from '~/types/interface'
 
 const features = [
-  "Logiciel de gestion et communication en ligne",
+  'Logiciel de gestion et communication en ligne',
   "Destiné aux établissements d'enseignement artistique",
-  "Gestion quotidienne et en temps réel",
-  "Pilotage complet de votre structure",
+  'Gestion quotidienne et en temps réel',
+  'Pilotage complet de votre structure',
 ]
 
 const pictos: Array<FeaturePicto> = [
   {
-    src: "/images/logiciels/school/picto1.png",
-    text: "Logiciel de gestion et communication full web",
+    src: '/images/pages/opentalent_school/presentation/picto1.png',
+    text: 'Logiciel de gestion et communication full web',
   },
   {
-    src: "/images/logiciels/school/picto2.png",
+    src: '/images/pages/opentalent_school/presentation/picto3.png',
     text: "Site web intégré & simple d'usage",
   },
   {
-    src: "/images/logiciels/school/picto3.png",
-    text: "Boostez votre visibilité & communication",
+    src: '/images/pages/opentalent_school/presentation/picto2.png',
+    text: 'Boostez votre visibilité & communication',
   },
   {
-    src: "/images/logiciels/school/picto4.png",
-    text: "Communiquez en réseau"
+    src: '/images/pages/opentalent_school/presentation/picto4.png',
+    text: 'Communiquez en réseau',
   },
-];
+]
 </script>

+ 14 - 14
components/Logiciels/School/Reviews.vue

@@ -11,39 +11,39 @@
 </template>
 
 <script setup lang="ts">
-import AnchoredSection from "~/components/Layout/AnchoredSection.vue";
-import type { Review } from "~/types/interface";
+import AnchoredSection from '~/components/Layout/AnchoredSection.vue'
+import type { Review } from '~/types/interface'
 
 const cards: Array<Review> = [
   {
     review:
       "C'est un logiciel simple d'utilisation après la formation. Pensé pour la musique, il s'adapte rès bien conçu et efficace avec une équipe ouverte, dynamique et à l'écoute. L’assistance est très réactive, j'ai toujours eu une réponse rapide à mes besoins, ce qui est fort appréciable.",
-    name: "Patrice CATHELIN ",
-    status: "Directeur administratif & pédagogique ",
-    structure: "Conservatoire de Musique & de Danse de Sens (78)",
+    name: 'Patrice CATHELIN ',
+    status: 'Directeur administratif & pédagogique ',
+    structure: 'Conservatoire de Musique & de Danse de Sens (78)',
   },
   {
     review:
       "Étant présente depuis presque le début, je suis fière d'avoir vu grandir ce logiciel et d'avoir évoluée avec lui. De plus, je me suis sentie écoutée lors de mes propositions d'amélioration, car beaucoup ont vu le jour. Enfin, l'accompagnement et la réactivité n'ont jamais faibli depuis toutes ces années",
-    name: "Karine GIRAUD",
-    status: "Secrétaire administrative",
-    structure: "Association Musicale Sainte Cécile de Lagord (17)",
+    name: 'Karine GIRAUD',
+    status: 'Secrétaire administrative',
+    structure: 'Association Musicale Sainte Cécile de Lagord (17)',
   },
   {
     review:
       "Logiciel très complet qui permet de faire beaucoup de choses. J’apprécie particulièrement la réactivité, la bienveillance et le fait que l’équipe soit à l'écoute pour faire évoluer l'outil en fonction de nos besoins. Si besoin, la FAQ est vraiment utile. Elle permet de trouver rapidement une solution face à un problème rencontré..",
-    name: "Laurent BEL",
-    status: "Directeur administratif & pédagogique",
-    structure: " École de Musique EPIC Musique en 4 Rivières (74)",
+    name: 'Laurent BEL',
+    status: 'Directeur administratif & pédagogique',
+    structure: ' École de Musique EPIC Musique en 4 Rivières (74)',
   },
   {
     review:
       "Opentalent est une entreprise avec de vraies valeurs humaines, à l'écoute de chaque structure et qui ne cesse de s'améliorer pour toujours coller aux besoins de ses clients. Plus qu'une relation commerciale, c'est pour nous un véritable partenaire au quotidien..",
-    name: "Philippe BORY",
-    status: "Personnel administratif",
+    name: 'Philippe BORY',
+    status: 'Personnel administratif',
     structure: "École d'Arts de Saint-Michel-sur-Orge (91)",
   },
-];
+]
 </script>
 
 <style scoped>

+ 57 - 63
components/Logiciels/School/SomeNumbers.vue

@@ -3,89 +3,83 @@
     <v-row class="align-center custom-row">
       <v-col cols="12">
         <v-row no-gutters>
-          <LayoutUISubTitle>
-            Quelques chiffres
-          </LayoutUISubTitle>
+          <LayoutUISubTitle> Quelques chiffres </LayoutUISubTitle>
 
           <LayoutUITitle>
-            Pour les petits comme pour les GRANDS établissements d'enseignement artistique
+            Pour les petits comme pour les GRANDS<br />établissements
+            d'enseignement artistique
           </LayoutUITitle>
         </v-row>
       </v-col>
     </v-row>
 
-    <v-container>
-      <v-row class="mb-12 card-container custom-row">
-        <v-col
-          cols="3"
-          class="d-flex justify-center align-center small-padding"
-        >
-          <CommonCardStat
-            number="30 > 1 500"
-            text="Élèves"
-          />
-        </v-col>
-        <v-col
-          cols="3"
-          class="d-flex justify-center align-center"
-        >
-          <CommonCardStat
-            number="234"
-            text="Clients"
-          />
-        </v-col>
-        <v-col
-          cols="3"
-          class="d-flex justify-center align-center"
-        >
-          <CommonCardStat
-            number="20 304"
-            text="Utilisateurs"
-          />
-        </v-col>
-        <v-col
-          cols="3"
-          class="d-flex justify-center align-center"
-        >
-          <CommonCardStat
-            number="13"
-            text="Années d'expérience"
-          />
-        </v-col>
-      </v-row>
-    </v-container>
-    <v-row />
+    <v-row class="mb-12 card-container center-90">
+      <v-col
+        lg="3"
+        md="6"
+        cols="12"
+        class="d-flex justify-center align-center small-padding"
+      >
+        <CommonCardStat number="30 > 1 500" text="Élèves" />
+      </v-col>
+      <v-col lg="3" md="6" cols="12" class="d-flex justify-center align-center">
+        <CommonCardStat number="139" text="Clients" />
+      </v-col>
+      <v-col lg="3" md="6" cols="12" class="d-flex justify-center align-center">
+        <CommonCardStat number="153 602" text="Utilisateurs" />
+      </v-col>
+      <v-col lg="3" md="6" cols="12" class="d-flex justify-center align-center">
+        <CommonCardStat number="17" text="Années d'expérience" />
+      </v-col>
+    </v-row>
 
-    <CommonCarouselClients :items="items" >
-      <template v-slot:title>
-        Plus de <span class="alt-color">5000 structures</span> nous font confiance
+    <CommonCarouselClients :items="items">
+      <template #title>
+        <span class="alt-color">139 structures</span> nous font
+        confiance
       </template>
     </CommonCarouselClients>
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-const items: Array<{ src: string }> = [
-  { src: "/images/reviews/school/review1.svg" },
-  { src: "/images/reviews/school/review2.png" },
-  { src: "/images/reviews/school/review3.png" },
-  { src: "/images/reviews/school/review4.jpeg" },
-  { src: "/images/reviews/school/review5.jpeg" },
-  { src: "/images/reviews/school/review6.jpeg" },
-];
+const items: Array<{ src: string; alt: string }> = [
+  {
+    src: '/images/pages/opentalent_school/reviews/Logo_Conservatoire_Les_Ateliers_des_Arts_Agglomeration_du_Puy-en-Velay.svg',
+    alt: 'Logo du Conservatoire « Les ateliers des arts',
+  },
+  {
+    src: '/images/pages/opentalent_school/reviews/Logo_Conservatoire-Senlis.png',
+    alt: 'Logo du Conservatoire de Senlis',
+  },
+  {
+    src: '/images/pages/opentalent_school/reviews/Logo_Ecole_de_Musique-Sausheim.png',
+    alt: 'Logo de l’École de musique Sausheim',
+  },
+  {
+    src: '/images/pages/opentalent_school/reviews/Logo_Conservatoire_Marly_le_Roi-Roger_Bourdin.jpeg',
+    alt: 'Logo du Conservatoire Marly le Roi Roger Bourdin',
+  },
+  {
+    src: '/images/pages/opentalent_school/reviews/Logo_Conservatoire_de_Musiques_et_de_Danses_du_Thouarsais.jpeg',
+    alt: 'Logo du Conservatoire de Musique et de Danse du Thouarsais',
+  },
+  {
+    src: '/images/pages/opentalent_school/reviews/Logo_Conservatoire_de_Musique_d_Annemasse.jpg',
+    alt: 'Logo du Conservatoire d’Annemasse',
+  },
+  {
+    src: '/images/pages/opentalent_school/reviews/Logo_EBAG-Ecole_des_Beaux-Arts_du_Genevois.png',
+    alt: 'Ecole des Beaux-Arts du Genevois',
+  },
+]
 </script>
 
 <style scoped lang="scss">
-.v-container {
+.card-container {
   --on-primary-color-alt: var(--secondary-color);
 }
 
-.custom-row {
-  width: 90%;
-  margin-right: auto;
-  margin-left: auto;
-}
-
 .v-row {
   max-width: 1600px;
   margin: 0 auto;

+ 15 - 6
components/Logiciels/Title.vue

@@ -1,18 +1,17 @@
-
 <template>
   <LayoutContainer>
     <div class="container-title">
-      <v-col cols="3" class="lateral-text">
+      <v-col v-if="mdAndUp" cols="3" class="lateral-text">
         <span>
-          <slot name="left-text"/>
+          <slot name="left-text" />
         </span>
       </v-col>
-      <v-col cols="6">
+      <v-col cols="12" md="6">
         <h1>
           <slot />
         </h1>
       </v-col>
-      <v-col cols="3" class="lateral-text">
+      <v-col v-if="mdAndUp" cols="3" class="lateral-text">
         <span>
           <slot name="right-text" />
         </span>
@@ -21,6 +20,12 @@
   </LayoutContainer>
 </template>
 
+<script setup lang="ts">
+import { useDisplay } from 'vuetify'
+
+const { mdAndUp } = useDisplay()
+</script>
+
 <style scoped lang="scss">
 .container-title {
   display: flex;
@@ -29,7 +34,6 @@
   align-items: center;
   text-align: center;
   letter-spacing: 0.18em;
-  border-bottom: 0.1rem solid var(--on-neutral-color-extra-light);
 }
 
 h1 {
@@ -37,6 +41,11 @@ h1 {
   line-height: 77px;
   color: var(--on-neutral-color);
   text-align: center;
+
+  @media (max-width: 600px) {
+    font-size: 42px;
+    line-height: 46px;
+  }
 }
 
 .lateral-text {

+ 48 - 42
components/News/Details.vue

@@ -1,14 +1,5 @@
 <template>
   <LayoutContainer>
-    <v-row>
-      <v-col cols="12">
-        <CommonBanner
-          imageSrc="/images/actu/pub.png"
-          imageAlt="banner"
-        />
-      </v-col>
-    </v-row>
-
     <div class="news-section">
       <v-row class="mb-6 center-90">
         <v-col class="d-flex align-items-center">
@@ -26,10 +17,7 @@
       <div>
         <div v-if="pending">
           <v-row class="justify-center progress">
-            <v-progress-circular
-              indeterminate
-              color="grey"
-            />
+            <v-progress-circular indeterminate color="grey" />
           </v-row>
         </div>
 
@@ -39,62 +27,75 @@
             :description="newsItem.leadText"
           />
 
-          <v-row class="center-90">
-            <v-col cols="6">
-              <v-img :src="getImageUrl(newsItem.attachment)"/>
+          <v-row class="center-90 mb-12">
+            <v-col cols="12" md="6">
+              <v-img :src="getImageUrl(newsItem.attachment)" cover />
             </v-col>
 
-            <v-col cols="6">
-              <h1>
+            <v-col cols="12" md="6" class="d-flex flex-column justify-center">
+              <h3>
                 {{ newsItem.title }}
-              </h1>
+              </h3>
+
+              <strong>
+                {{ newsItem.leadText }}
+              </strong>
             </v-col>
           </v-row>
 
           <v-row class="center-90">
-            <p
-              v-html="newsItem.bodyText"
-              class="description"
-            />
+            <p class="description" v-html="newsItem.bodyText" />
           </v-row>
 
           <v-row class="d-flex justify-center align-center">
-            <v-btn prepend-icon="fas fa-info" class="btn-plus mb-12" text>
+            <v-btn
+              v-if="newsItem.linkButton"
+              :href="newsItem.linkButton"
+              target="_blank"
+              class="btn-plus mb-12"
+              :text="true"
+            >
               En savoir plus
             </v-btn>
           </v-row>
 
           <v-row class="d-flex justify-space-between center-90">
-            <p>
-              MOTS CLÉS
-            </p>
             <div>
+              <p v-if="newsItem.tags.length > 0">MOTS CLÉS</p>
+            </div>
+            <div v-if="mdAndUp">
               <p>PARTAGER</p>
             </div>
           </v-row>
 
           <v-row class="d-flex justify-space-between mb-8 center-90">
             <p class="key-word mt-3">
-              <span v-for="tag in newsItem.tags" class="mr-2">
+              <span v-for="tag in newsItem.tags" :key="tag.id" class="mr-2">
                 {{ tag.name }}
               </span>
             </p>
 
-            <CommonShare />
+            <CommonShare v-if="mdAndUp" />
           </v-row>
+
+          <div v-if="smAndDown" class="center-90">
+            <p>PARTAGER</p>
+            <CommonShare />
+          </div>
         </div>
       </div>
     </div>
-
-    <CommonAgenda />
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-import { useEntityFetch } from "~/composables/data/useEntityFetch";
-import News from "~/models/Maestro/News";
+import { useDisplay } from 'vuetify'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import News from '~/models/Maestro/News'
 
-const route = useRoute();
+const { mdAndUp, smAndDown } = useDisplay()
+
+const route = useRoute()
 const { fetch } = useEntityFetch()
 const config = useRuntimeConfig()
 
@@ -116,27 +117,32 @@ const getImageUrl = (attachment: string): string | null => {
 <style scoped>
 .news {
   .v-img {
-    width: 80%;
-    margin-left: 3.5rem;
+    max-height: 600px;
+    margin-left: auto;
     margin-right: auto;
   }
 
-  h1 {
-    margin-top: 11rem;
+  h3 {
     text-decoration: none;
     text-transform: uppercase;
     font-size: 36px;
     font-weight: 600;
+    color: var(--primary-color);
+  }
+
+  strong {
+    font-size: 21px;
+    margin-top: 16px;
   }
 
   .description {
     color: var(--primary-color);
-    text-align: justify;
-    font-size: 30px;
+    max-width: 80%;
+    font-size: 21px;
     font-weight: 500;
     line-height: 34px;
-    margin-left: 3.5rem;
-    margin-right: 3.5rem;
+    margin-left: auto;
+    margin-right: auto;
     margin-bottom: 3rem;
   }
 

+ 48 - 36
components/News/List.vue

@@ -1,21 +1,12 @@
 <template>
-  <h1 id="news-anchor" class="title mt-12 mb-12">
-    Toutes les news
-  </h1>
-
   <div v-if="pending">
     <v-row class="justify-center progress">
-      <v-progress-circular
-        indeterminate
-        color="grey"
-      />
+      <v-progress-circular indeterminate color="grey" />
     </v-row>
   </div>
 
-  <div v-else-if="!newsCollection || !(newsCollection!.items)">
-    <v-row class="justify-center">
-      Aucun résultat trouvé
-    </v-row>
+  <div v-else-if="!newsCollection || !newsCollection!.items">
+    <v-row class="justify-center"> Aucun résultat trouvé </v-row>
   </div>
 
   <div v-else>
@@ -28,17 +19,16 @@
         <v-card-item>
           <v-container fluid>
             <v-row align="center">
-              <v-col cols="3">
+              <v-col cols="12" lg="3">
                 <v-img
                   v-if="newsItem.attachment"
                   :src="getImageUrl(newsItem.attachment)"
                   alt="poster"
-                  height="200"
-                  width="400"
+                  cover
                 />
               </v-col>
 
-              <v-col cols="9">
+              <v-col cols="12" lg="9">
                 <div class="details">
                   <NuxtLink
                     :to="`/actualites/${newsItem.id}`"
@@ -71,8 +61,7 @@
                         <v-card-actions class="justify-end">
                           <v-btn
                             :to="`/actualites/${newsItem.id}`"
-                            prepend-icon="fas fa-info"
-                            class="btn mr-2 mb-1"
+                            class="inv-theme btn mr-2 mb-1"
                           >
                             En savoir plus
                           </v-btn>
@@ -94,8 +83,8 @@
           v-if="newsCollection && newsCollection.pagination"
           :model-value="page"
           :pagination="newsCollection.pagination"
-          @update:model-value="onPageUpdated"
           class="mt-4"
+          @update:model-value="onPageUpdated"
         />
       </v-col>
     </v-row>
@@ -103,28 +92,32 @@
 </template>
 
 <script setup lang="ts">
-import { useEntityFetch } from "~/composables/data/useEntityFetch";
-import News from "~/models/Maestro/News";
+import type { ComputedRef, Ref } from 'vue'
+import { useEntityFetch } from '~/composables/data/useEntityFetch'
+import News from '~/models/Maestro/News'
 
-const i18n = useI18n();
-const config = useRuntimeConfig();
+const config = useRuntimeConfig()
 const { fetchCollection } = useEntityFetch()
 
 const getImageUrl = (attachment: string) =>
-  `${config.public.apiBaseUrl}/uploads/news/${attachment}`;
+  `${config.public.apiBaseUrl}/uploads/news/${attachment}`
 
-const page: Ref<number> = ref(1);
+const page: Ref<number> = ref(1)
 
 const query: ComputedRef<Record<string, string | number>> = computed(() => {
   return {
     page: page.value,
-    type: "ENTREPRISE",
-    "startPublication[before]": "now",
-    "endPublication[after]": "now"
-  };
-});
+    type: 'BUSINESS',
+    'startPublication[before]': 'now',
+    'endPublication[after]': 'now',
+  }
+})
 
-const { data: newsCollection, pending, refresh } = fetchCollection(News, null, query)
+const {
+  data: newsCollection,
+  pending,
+  refresh,
+} = fetchCollection(News, null, query)
 
 const onPageUpdated = async (newVal: number): Promise<void> => {
   page.value = newVal
@@ -151,11 +144,15 @@ h1 {
   font-size: 4rem;
   font-weight: 600;
   line-height: 42px;
+
+  @media (max-width: 600px) {
+    font-size: 2.5rem;
+  }
 }
 
 .news {
   .v-card {
-    border-radius: 10px;
+    border-radius: 14px;
     min-width: 100%;
     margin-bottom: 1rem;
     margin-left: 2rem;
@@ -175,22 +172,37 @@ h1 {
   }
 
   .v-img {
-    width: 80%;
-    margin-left: auto;
-    margin-right: auto;
+    width: 100%;
+    max-height: 160px;
+    margin: 12px;
+    border-radius: 14px;
+
+    @media (max-width: 1240px) {
+      width: 97%;
+      margin: 1.5%;
+    }
   }
 
   .details {
     border: 1px solid var(--neutral-color) !important;
     padding: 9px;
-    border-radius: 20px;
+    border-radius: 24px;
     width: 99%;
 
+    @media (max-width: 1240px) {
+      width: 94%;
+      margin: -18px 3% 12px;
+    }
+
     .v-card-title {
       color: var(--neutral-color);
       font-size: 36px;
       font-weight: 600;
       line-height: 39px;
+
+      @media (max-width: 1240px) {
+        font-size: 24px;
+      }
     }
 
     .star {

+ 132 - 145
components/Webinaire/Catalogue.vue

@@ -1,37 +1,29 @@
 <template>
   <LayoutContainer>
-    <div class="grey-container">
+    <div>
       <v-row class="center-90">
-        <LayoutUISubTitle>
-          Des webinaires pour tous
-        </LayoutUISubTitle>
+        <LayoutUISubTitle> Des webinaires pour tous </LayoutUISubTitle>
       </v-row>
 
       <v-row class="center-90">
         <v-col cols="12" class="section-title">
-          <h3>
-            SIMPLIFIEZ LA GESTION ET LA COMMUNICATION DE VOTRE STRUCTURE CULTURELLE
-          </h3>
+          <h3>Simplifiez la gestion et la communication de votre structure</h3>
 
           <div class="strong-label">
-            Votre orchestre, école de danse ou votre fédération mérite les outils les plus performants du marché pour briller en toute simplicité.
-            Découvrez comment nos outils peuvent transformer votre quotidien :
+            Votre structure culturelle, établissement d’enseignement artistique
+            ou fédération mérite les outils les plus performants du marché pour
+            briller en toute simplicité. Découvrez comment nos outils peuvent
+            transformer votre quotidien :
           </div>
         </v-col>
       </v-row>
 
       <v-row class="center-90 catalog">
-        <v-col
-          v-for="(course, index) in courses"
-          :key="index"
-          cols="4"
-        >
+        <v-col v-for="(course, index) in courses" :key="index" cols="12" md="4">
           <v-card class="mb-4">
             <v-card-text>
               <div class="title-card-container">
-                <v-img
-                  :src="course.imageUrl"
-                />
+                <v-img :src="course.imageUrl" :alt="course.imageAlt" />
 
                 <h4>
                   {{ course.title }}
@@ -43,9 +35,7 @@
               </p>
 
               <div class="objectives mt-6">
-                <h6>
-                  Objectifs
-                </h6>
+                <h6>Objectifs</h6>
 
                 <ul>
                   <li
@@ -57,10 +47,10 @@
                 </ul>
               </div>
 
+              <div class="badge-time">Durée : {{ course.duration }}</div>
+
               <div class="program">
-                <h6>
-                  Programme
-                </h6>
+                <h6>Programme</h6>
 
                 <v-row>
                   <v-col
@@ -80,22 +70,11 @@
                 </v-row>
               </div>
 
-              <v-chip class="badge-time">
-                <span>
-                  Durée : {{ course.duration }}
-                </span>
-              </v-chip>
-
-              <v-chip class="badge-time">
-                <span>
-                  {{ course.price }}
-                </span>
-              </v-chip>
+              <div class="badge-time">
+                {{ course.price }}
+              </div>
 
-              <v-chip
-                class="chip-register"
-                @click="showModal(course.title)"
-              >
+              <v-chip class="chip-register" @click="showModal(course.title)">
                 Inscrivez-vous
               </v-chip>
             </v-card-text>
@@ -108,173 +87,174 @@
     <v-dialog
       v-model="modalShowing"
       max-width="800"
+      :retain-focus="false"
+      :scrollable="true"
       class="calendar-modal"
     >
-      <div class="alt-theme d-flex flex-column align-center">
-        <LayoutUISubTitle>
-          Inscrivez vous
-        </LayoutUISubTitle>
-
-        <h4 class="title-inscription text-center mt-4">
-          Vous y êtes presque !
-        </h4>
-
-        <iframe
-          :src="webinaireCalendars[selectedWebinar]"
-          width="700"
-          height="700"
-        />
-
-        <v-row>
-          <v-col cols="12">
-            <v-btn
-              class="close-button"
-              @click="closeModal()"
+      <template v-slot:default="{ isActive }">
+        <div class="alt-theme d-flex flex-column align-center">
+            <v-card
+              title="Inscrivez vous"
             >
-              Fermer
-            </v-btn>
-          </v-col>
-        </v-row>
-      </div>
+              <v-card-text style="height: 70vh;">
+                <h4 class="title-inscription text-center mt-4">
+                  Vous y êtes presque !
+                </h4>
+
+                <iframe
+                  :src="webinaireCalendars[selectedWebinar]"
+                  width="700"
+                  height="700"
+                />
+              </v-card-text>
+            </v-card>
+
+            <v-row>
+              <v-col cols="12">
+                <v-btn class="close-button" @click="closeModal()"> Fermer </v-btn>
+              </v-col>
+            </v-row>
+        </div>
+      </template>
     </v-dialog>
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-import type { Training } from "~/types/interface";
-
-const downloadPdf = (pdfUrl: string) => {
-  window.open(pdfUrl, "_blank");
-};
+import type { Ref } from 'vue'
+import type { Training } from '~/types/interface'
 
 const courses: Array<Training> = [
   {
-    imageUrl: "/images/logo/logiciels/&_Jaune.png",
-    title: "Webinaire Artist ",
+    imageUrl: '/images/logos/opentalent/Logo_Opentalent_Artist_Griffe.png',
+    imageAlt: 'Esperluette du logo Opentalent Artist',
+    title: 'Webinaire Artist ',
     description:
-      "Ce webinaire est destiné aux acteurs culturels tels que les orchestres, les chorales, les compagnies et troupes de danse, théâtre et cirque. Il vous permettra de découvrir les fonctionnalités du logiciels, les avantages et les différentes versions.. ",
+      'Ce webinaire est destiné aux acteurs culturels tels que les orchestres, les chorales, les compagnies et troupes de danse, théâtre et cirque. Il vous permettra de découvrir les fonctionnalités du logiciels, les avantages et les différentes versions.. ',
     objectives: [
-      "Découvrir le logiciel Opentalent Artist",
-      "Présentation des principales fonctionnalités",
-      "Quelles sont les différences entre les versions Standard & Premium ?",
-      "Qu'est ce que l'Agenda culturel et l'annuaire ? ",
+      'Obtenir une présentation du logiciel Opentalent Artist',
+      'Présentation des principales fonctionnalités',
+      "Qu'est ce que l'agenda culturel et l'annuaire ? ",
+      'Quelles différences entre la version Standard & Premium ?',
     ],
-    duration: "1H30",
+    duration: '1H30',
     additionalObjectives: [
       {
         id: 1,
         objectives: [
-          "Accès et interface",
-          "Configuration",
-          "Répertoire",
-          "Agenda",
+          'Accès et interface',
+          'Configuration',
+          'Répertoire',
+          'Agenda',
         ],
       },
       {
         id: 2,
         objectives: [
-          "Parc matériel",
-          "Rapport d’activité",
-          "Site internet",
-          "Communication",
+          'Parc matériel',
+          'Rapport d’activité',
+          'Communication',
+          'Site internet',
         ],
       },
     ],
-    price: "Gratuit",
+    price: 'Gratuit',
     downloadLink:
-      "https://www.opentalent.fr/fileadmin/stockage/stockage/support/programme/PF-School-2023-02_2-jours.pdf",
+      'https://www.opentalent.fr/fileadmin/stockage/stockage/support/programme/PF-School-2023-02_2-jours.pdf',
   },
   {
     // number: "02",
-    title: "Webinaire School",
-    imageUrl: "/images/logo/logiciels/&_Bleu.png",
+    title: 'Webinaire School',
+    imageUrl: '/images/logos/opentalent/Logo_Opentalent_School_Griffe.png',
+    imageAlt: 'Esperluette du logo Opentalent School',
     description:
       " Rejoignez notre webinaire dédié aux petits comme aux GRANDS établissements d'enseignement artistique et découvrez comment optimiser votre travail grâce à un outil professionnel.",
     objectives: [
-      "Découvrir le logiciel Opentalent School",
+      'Obtenir une présentation du logiciel Opentalent School',
       "Comprendre l'écosystème de l'outil",
-      "Présentation des principales fonctionnalités",
-      "Identifier les avantages de cet outil pour votre structure",
+      "Identifier les avantages qu'offre ce logiciel pour votre structure",
+      'Apprendre à gérer votre propre site internet',
     ],
-    duration: "1h",
+    duration: '1h',
     additionalObjectives: [
       {
         id: 1,
         objectives: [
-          "Accès et interface",
-          "Configuration",
-          "Répertoire",
-          "Agenda",
+          'Accès et interface',
+          'Configuration',
+          'Répertoire',
+          'Agenda',
         ],
       },
       {
         id: 2,
         objectives: [
-          "Parc matériel",
-          "Rapport d’activité",
-          "Site internet",
-          "Communication",
+          'Parc matériel',
+          'Facturation',
+          'Communication',
+          'Site internet',
         ],
       },
     ],
-    price: "Gratuit",
+    price: 'Gratuit',
     downloadLink:
-      "https://www.opentalent.fr/fileadmin/stockage/stockage/support/programme/PF-School-2023-02_1-jour.pdf",
+      'https://www.opentalent.fr/fileadmin/stockage/stockage/support/programme/PF-School-2023-02_1-jour.pdf',
   },
   {
-    title: "Webinaire Manager",
-    imageUrl: "/images/logo/logiciels/&_Rouge.png",
+    title: 'Webinaire Manager',
+    imageUrl: '/images/logos/opentalent/Logo_Opentalent_Manager_Griffe.png',
+    imageAlt: 'Esperluette du logo Opentalent Manager',
     description:
       "Ces webinaires  sont spécialement conçues pour les utilisateurs du logiciel fédéral de la CMF (Confédération Musicale de France). Gagner en temps administratif, booster vos performances et optimiser l'utilisation du logiciel.",
     objectives: [
       "Configurer l'appel de cotisation",
       "Suivre l'appel de cotisation",
-      "Gérer votre site internet (débutants)",
-      "Gérer votre site internet (confirmés)",
+      'Gérer votre site internet (pour les débutants)',
+      'Gérer votre site internet (pour les confirmés)',
     ],
-    duration: "1H30",
+    duration: '1H30',
     additionalObjectives: [
       {
         id: 1,
         objectives: [
-          "Mieux connaitre votre logiciel",
-          "Optimiser votre temps administratif",
+          'Mieux connaitre votre logiciel',
+          'Optimiser votre temps administratif',
         ],
       },
       {
         id: 2,
         objectives: [
-          "Communiquer avec votre réseau",
-          "Promouvoir votre organisation",
+          'Communiquer avec votre réseau',
+          'Promouvoir votre organisation',
         ],
       },
     ],
-    price: "Gratuit",
+    price: 'Gratuit',
     downloadLink:
-      " https://www.opentalent.fr/fileadmin/stockage/stockage/support/programme/PF-Typo3-2023-02_1-jour.pdf",
+      ' https://www.opentalent.fr/fileadmin/stockage/stockage/support/programme/PF-Typo3-2023-02_1-jour.pdf',
   },
-];
+]
 
-const selectedWebinar: Ref<string | null> = ref(null);
+const selectedWebinar: Ref<string | null> = ref(null)
 
 const webinaireCalendars: Record<string, string> = {
-  "Webinaire Artist":
-    "https://widget.weezevent.com/ticket/E920851/?code=62708&locale=fr-FR&width_auto=1&color_primary=0e2d32",
-  "Webinaire School":
-    "https://widget.weezevent.com/ticket/E963899/?code=47365&locale=fr-FR&width_auto=1&color_primary=0e2d32",
-  "Webinaire Manager":
-    "https://widget.weezevent.com/ticket/E923624/?code=4857&locale=fr-FR&width_auto=1&color_primary=0e2d32",
-};
+  'Webinaire Artist':
+    'https://widget.weezevent.com/ticket/E920851/?code=62708&locale=fr-FR&width_auto=1&color_primary=0e2d32',
+  'Webinaire School':
+    'https://widget.weezevent.com/ticket/E963899/?code=47365&locale=fr-FR&width_auto=1&color_primary=0e2d32',
+  'Webinaire Manager':
+    'https://widget.weezevent.com/ticket/E923624/?code=4857&locale=fr-FR&width_auto=1&color_primary=0e2d32',
+}
 
 const showModal = (webinaireTitle: string) => {
-  selectedWebinar.value = webinaireTitle.trim();
-};
+  selectedWebinar.value = webinaireTitle.trim()
+}
 
 const modalShowing = computed(() => selectedWebinar.value)
 
 const closeModal = () => {
-  selectedWebinar.value = null;
-};
+  selectedWebinar.value = null
+}
 </script>
 
 <style scoped lang="scss">
@@ -287,30 +267,27 @@ const closeModal = () => {
 .section-title {
   display: flex;
   flex-direction: column;
-  align-items: center;
 
   h3 {
-    font-size: 2rem;
-    letter-spacing: .1rem;
+    font-size: 42px;
+    letter-spacing: 0.1rem;
     line-height: 3.5rem;
-    margin-bottom: .5rem;
+    margin-bottom: 0.5rem;
     margin-top: 2rem;
-    text-transform: uppercase;
   }
 
   .strong-label {
     font-size: 1.5rem;
     font-weight: 400 !important;
-    letter-spacing: .1rem;
+    letter-spacing: 0.1rem;
     line-height: 2rem;
     margin-bottom: 1rem;
-    text-align: center;
-    text-transform: uppercase;
   }
 }
 
 .catalog {
   padding: 2rem;
+  background: var(--neutral-color-alt-light);
 
   .title-card-container {
     display: flex;
@@ -343,18 +320,25 @@ const closeModal = () => {
     color: var(--primary-color);
     margin-top: 1rem;
     margin-bottom: 0.5rem;
-    height: 5rem;
+
+    @media (min-width: 600px) {
+      height: 5rem;
+    }
   }
 
-  .objectives, .program {
+  .objectives,
+  .program {
     justify-content: space-between;
     align-items: center;
-    background: var(--secondary-color);
+    background: var(--secondary-color-light);
     margin-top: 1rem;
     margin-bottom: 1rem;
     border-radius: 1rem;
     padding: 1rem 1rem 1rem 1.5rem;
-    height: 11rem;
+
+    @media (min-width: 600px) {
+      height: 11rem;
+    }
 
     h6 {
       font-weight: 500;
@@ -383,17 +367,20 @@ const closeModal = () => {
   }
 
   .badge-time {
-    color: var(--neutral-color);
-    border: 1px solid var(--primary-color);
-  }
-
-  .badge-time span {
     color: var(--primary-color);
+    background: var(--neutral-color);
+    width: 100%;
+    height: 36px;
+    text-align: center;
+    font-size: 18px;
+    font-weight: 500;
+    border-radius: 12px;
+    vertical-align: center;
+    padding-top: 6px;
   }
 }
 
 .calendar-modal {
-
   h4 {
     font-weight: 600;
     font-size: 2rem;
@@ -402,7 +389,7 @@ const closeModal = () => {
   }
 
   .close-button {
-    background-color: #e34461;  /* TODO: pqoi cette couleur ici? */
+    background-color: #e34461; /* TODO: pqoi cette couleur ici? */
     color: var(--on-primary-color);
     font-weight: 500;
     font-size: 14px;

+ 46 - 50
components/Webinaire/FAQ.vue

@@ -4,93 +4,86 @@ Foire aux questions
 <template>
   <LayoutContainer>
     <v-row class="center-90">
-      <LayoutUISubTitle>
-        Des questions ?
-      </LayoutUISubTitle>
+      <LayoutUISubTitle> Des questions ? </LayoutUISubTitle>
     </v-row>
 
     <v-row class="center-90">
       <v-col cols="12" class="section-title">
-        <h3>
-          Tout savoir sur nos webinaire en ligne
-        </h3>
+        <h3>Tout savoir sur nos webinaire en ligne</h3>
 
-        <div class="strong-label">
-          Les questions les plus fréquentes
-        </div>
+        <div class="strong-label">Les questions les plus fréquentes</div>
       </v-col>
     </v-row>
 
-    <div class="faq">
-      <div
-        v-for="(item, index) in faqItems"
-        :key="index"
-        class="faq-item"
-      >
+    <div class="faq center-90">
+      <div v-for="(item, index) in faqItems" :key="index" class="faq-item">
         <div
-          class="question"
+          :class="'question' + (isOpen(index) ? ' open' : '')"
           @click="toggle(index)"
         >
-          <v-icon icon="fas fa-circle" />
+          <v-icon v-if="isOpen(index)" icon="fas fa-angle-down" />
+          <v-icon v-else icon="fas fa-angle-right" />
           {{ item.question }}
         </div>
 
-        <div
-          v-if="isOpen(index)"
-          class="answer"
-        >
-          {{ item.answer }}
-        </div>
+        <div v-if="isOpen(index)" class="answer" v-html="item.answer" />
       </div>
     </div>
   </LayoutContainer>
 </template>
 
 <script setup lang="ts">
-import type { FaqEntry } from "~/types/interface";
+import type { Ref } from 'vue'
+import type { FaqEntry } from '~/types/interface'
 
 const faqItems: Array<FaqEntry> = [
   {
     question: 'Comment s’inscrire à un webinaire?',
-    answer: 'Pour vous inscrire à un webinaire, suivez le lien "Inscrivez-vous" correspondant au cours qui vous intéresse.',
+    answer:
+      'Pour vous inscrire à un webinaire, suivez le lien "Inscrivez-vous" correspondant au cours qui vous intéresse.',
   },
   {
     question: 'Combien de temps dure nos webinaires ?',
-    answer: 'Nos webinaires durent en moyenne 1H30. Les sessions de questions/réponses peuvent parfois prolonger la durée prévue de nos webinaires.',
+    answer:
+      'Nos webinaires durent en moyenne 1H30. Les sessions de questions/réponses peuvent parfois prolonger la durée prévue de nos webinaires.',
   },
   {
     question: 'Comment se passe un webinaire ?',
-    answer: 'Inscrivez-vous à l\'un de nos webinaires en choisissant une date sur l\'agenda et renseignez vos informations. ' +
-            'Vous recevrez à la suite de votre inscription sur notre site, un email de confirmation avec un rappel de la date et de l\'horaire de participation ainsi que l\'URL de connexion pour le webinaire. ' +
-            'Un mail de relance à J-1 vous sera envoyer vous rappelant votre participation au webinaire. ' +
-            'Le jour J, cliquez sur l\'URL de connexion. Nous vous encourageons à arriver quelques minutes en avance pour vous assurer de pouvoir accéder au webinaire sans aucun problème technique. ' +
-            'Lors du début du webinaire, toutes les instructions nécessaires vous seront fournies.'
+    answer:
+      "Inscrivez-vous à l'un de nos webinaires en choisissant une date sur l'agenda et renseignez vos informations. " +
+      "Vous recevrez à la suite de votre inscription sur notre site, un email de confirmation avec un rappel de la date et de l'horaire de participation ainsi que l'URL de connexion pour le webinaire. " +
+      'Un mail de relance à J-1 vous sera envoyer vous rappelant votre participation au webinaire. ' +
+      "Le jour J, cliquez sur l'URL de connexion. Nous vous encourageons à arriver quelques minutes en avance pour vous assurer de pouvoir accéder au webinaire sans aucun problème technique. " +
+      'Lors du début du webinaire, toutes les instructions nécessaires vous seront fournies.',
   },
   {
     question: 'De quel matériel aurais-je besoin pour suivre le webinaire ?',
-    answer: 'Pour plus de confort, il est recommandé d\'être équipé d\'un outil (de préférence un ordinateur) disposant d\'un micro et de haut-parleur.',
+    answer:
+      "Pour plus de confort, il est recommandé d'être équipé d'un outil (de préférence un ordinateur) disposant d'un micro et de haut-parleur.",
   },
   {
-    question: 'Y-a-t\'il une limite de participants ?',
-    answer: 'Il n\'y a pas de limite de participants lors de nos webinaires. Cependant, nous nous réservons le droit d\'annuler une session si le nombre de participants est inférieur à 3 personnes.',
+    question: "Y-a-t'il une limite de participants ?",
+    answer:
+      "Il n'y a pas de limite de participants lors de nos webinaires. Cependant, nous nous réservons le droit d'annuler une session si le nombre de participants est inférieur à 3 personnes.",
   },
   {
-    question: 'J\'ai besoin d\'aide...',
-    answer: 'Notre équipe est là pour vous. <button style="background-color: #0E2D32; color: #fff; border: none;border-radius: 4px;padding: 0.5rem 1rem;cursor: pointer;"   class="contact-btn" onclick="window.location.href=\'/nous-contacter\'">Contactez-nous</button>'
-}];
+    question: "J'ai besoin d'aide...",
+    answer:
+      'Notre équipe est là pour vous. <br/><button style="background-color: #0E2D32; color: #fff; border: none;border-radius: 4px;padding: 0.5rem 1rem;cursor: pointer;margin-top: 6px;"   class="contact-btn" onclick="window.location.href=\'/nous-contacter\'">Contactez-nous</button>',
+  },
+]
 
-const activeIndex: Ref<number | null> = ref(null);
+const activeIndex: Ref<number | null> = ref(null)
 
 function toggle(index: number) {
-  activeIndex.value = activeIndex.value === index ? null : index;
+  activeIndex.value = activeIndex.value === index ? null : index
 }
 
 function isOpen(index: number) {
-  return activeIndex.value === index;
+  return activeIndex.value === index
 }
 </script>
 
-
 <style scoped lang="scss">
 .section-title {
   display: flex;
@@ -98,18 +91,17 @@ function isOpen(index: number) {
   align-items: center;
 
   h3 {
-    font-size: 2rem;
-    letter-spacing: .1rem;
+    font-size: 42px;
+    letter-spacing: 0.1rem;
     line-height: 3.5rem;
-    margin-bottom: .5rem;
+    margin-bottom: 0.5rem;
     margin-top: 2rem;
-    text-transform: uppercase;
   }
 
   .strong-label {
     font-size: 1.5rem;
     font-weight: 400 !important;
-    letter-spacing: .1rem;
+    letter-spacing: 0.1rem;
     line-height: 2rem;
     margin-bottom: 1rem;
     text-align: center;
@@ -143,17 +135,21 @@ function isOpen(index: number) {
   }
 
   .v-icon {
-    font-size: 10px !important;
+    font-size: 16px !important;
     color: var(--on-primary-color-alt);
     margin-right: 0.5rem;
   }
 }
 
+.question.open {
+  border-radius: 4px 4px 0 0;
+}
+
 .answer {
-  background-color: var(--secondary-color);
+  background-color: var(--secondary-color-light);
   padding: 0.5rem 1rem;
-  border: 1px solid var(--neutral-color-alt-strong);
-  border-top: none;
+  border: none;
   border-radius: 0 0 4px 4px;
+  box-shadow: -1px 2px 6px 3px var(--on-neutral-color-extra-light);
 }
 </style>

Some files were not shown because too many files changed in this diff