generated from gitea_admin/default
finalisation home page
This commit is contained in:
266
app/components/BannierePros.vue
Normal file
266
app/components/BannierePros.vue
Normal file
@@ -0,0 +1,266 @@
|
||||
<!-- Utilisé pour : -->
|
||||
<!-- Index.vue / Encart PROS bas de page -->
|
||||
|
||||
<template>
|
||||
<div class="banniere_pros_wp">
|
||||
<div class="studio_img">
|
||||
<DsMedia src="/contenus/studio_img_1.webp" alt="Image du studio pro" ratio="16-9" />
|
||||
</div>
|
||||
<div class="banniere_pros--description studio_description">
|
||||
<div>
|
||||
<img src="/img/logos/logo_le_studio_noir.png" alt="Logo du studio pro" width="200">
|
||||
</div>
|
||||
<DsHeading as="h5" tone="default" class="banniere_pros--description--titre">
|
||||
On enregistre au studio !
|
||||
</DsHeading>
|
||||
<DsText as="p" tone="default" :clamp="3">
|
||||
Un grand studio modulaire ouvert à tous les professionnels aux portes de Paris
|
||||
</DsText>
|
||||
</div>
|
||||
<div class="parc_img">
|
||||
<DsMedia src="/contenus/studio_img_2.webp" alt="Image du studio pro" ratio="16-9" />
|
||||
</div>
|
||||
<div class="banniere_pros--description parc_description">
|
||||
<div>
|
||||
<img src="/img/logos/logo_le_parc_noir.png" alt="Logo du parc instrumental pro" width="150">
|
||||
</div>
|
||||
<DsHeading as="h5" tone="default" class="banniere_pros--description--titre">
|
||||
+ de 3 000 instruments en location
|
||||
</DsHeading>
|
||||
<DsText as="p" tone="default" :clamp="3">
|
||||
Location d’instruments de musique pour les professionnels et les amateurs
|
||||
</DsText>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import DsMedia from '@root/design-system/primitives/DsMedia.vue'
|
||||
import DsText from '@root/design-system/primitives/DsText.vue'
|
||||
import DsHeading from '@root/design-system/primitives/DsHeading.vue'
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.banniere_pros_wp {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
@media (max-width: 599px) {
|
||||
.banniere_pros_wp {
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 500px) {
|
||||
.banniere_pros_wp {
|
||||
row-gap: 50px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 399px) {
|
||||
.banniere_pros_wp {
|
||||
grid-template-columns: 30px 240px;
|
||||
grid-template-rows: 130px 60px 130px 42px 111px 70px 140px;
|
||||
//justify-content: center;
|
||||
.ds-media--16-9 {
|
||||
aspect-ratio: 4 / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (min-width: 400px) {
|
||||
.banniere_pros_wp {
|
||||
grid-template-columns: 80px 290px;
|
||||
grid-template-rows: 150px 60px 130px 42px 170px 70px 140px;
|
||||
//justify-content: center;
|
||||
.ds-media--16-9 {
|
||||
aspect-ratio: 4 / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (min-width: 500px) {
|
||||
.banniere_pros_wp {
|
||||
grid-template-columns: 150px 270px 40px 40px;
|
||||
grid-template-rows: auto;
|
||||
//justify-content: center;
|
||||
align-items: center;
|
||||
.ds-media--16-9 {
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
.banniere_pros_wp {
|
||||
grid-template-columns: 220px 250px 40px 40px;
|
||||
grid-template-rows: auto;
|
||||
//justify-content: center;
|
||||
align-items: center;
|
||||
.ds-media--16-9 {
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (min-width: 700px) {
|
||||
.banniere_pros_wp {
|
||||
grid-template-columns: 220px 250px 40px 40px;
|
||||
grid-template-rows: auto;
|
||||
//justify-content: center;
|
||||
align-items: center;
|
||||
.ds-media--16-9 {
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
.banniere_pros_wp {
|
||||
grid-template-columns: 100px 190px 20px 40px 110px 140px 160px;
|
||||
grid-template-rows: auto;
|
||||
align-items: center;
|
||||
.ds-media--16-9 {
|
||||
aspect-ratio: 4 / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (min-width: 900px) {
|
||||
.banniere_pros_wp {
|
||||
grid-template-columns: 130px 190px 40px 30px 160px 130px 169px;
|
||||
grid-template-rows: auto;
|
||||
align-items: center;
|
||||
.ds-media--16-9 {
|
||||
aspect-ratio: 4 / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1000px) {
|
||||
.banniere_pros_wp {
|
||||
grid-template-columns: 160px 200px 90px 50px 160px 150px 150px;
|
||||
grid-template-rows: auto;
|
||||
align-items: center;
|
||||
.ds-media--16-9 {
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1100px) {
|
||||
.banniere_pros_wp {
|
||||
grid-template-columns: 200px 200px 100px 50px 200px 150px 150px;
|
||||
grid-template-rows: auto;
|
||||
align-items: center;
|
||||
.ds-media--16-9 {
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.banniere_pros_wp {
|
||||
grid-template-columns: 230px 200px 100px 50px 230px 150px 150px;
|
||||
grid-template-rows: auto;
|
||||
align-items: center;
|
||||
.ds-media--16-9 {
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1300px) {
|
||||
.banniere_pros_wp {
|
||||
grid-template-columns: 270px 200px 100px 50px 270px 150px 150px;
|
||||
grid-template-rows: auto;
|
||||
align-items: center;
|
||||
.ds-media--16-9 {
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1400px) {
|
||||
.banniere_pros_wp {
|
||||
grid-template-columns: 320px 200px 100px 50px 320px 150px 150px;
|
||||
grid-template-rows: auto;
|
||||
align-items: center;
|
||||
.ds-media--16-9 {
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* IMAGES */
|
||||
.studio_img {
|
||||
grid-column: 1 / 3;
|
||||
grid-row: 1;
|
||||
z-index: 1;
|
||||
}
|
||||
@media (max-width: 499px) {
|
||||
.studio_img {
|
||||
grid-column: 1 / 3;
|
||||
grid-row: 1/2;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.parc_img {
|
||||
grid-column: 4 / 7;
|
||||
grid-row: 1;
|
||||
z-index: 1;
|
||||
}
|
||||
@media (max-width: 799px) {
|
||||
.parc_img {
|
||||
grid-column: 1 / 3;
|
||||
grid-row: 2;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
@media (max-width: 499px) {
|
||||
.parc_img {
|
||||
grid-column: 1 / 3;
|
||||
grid-row: 5/6;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* DESCRIPTIONS (au-dessus des images) */
|
||||
.studio_description {
|
||||
grid-column: 2 / 5;
|
||||
grid-row: 1;
|
||||
z-index: 2;
|
||||
}
|
||||
@media (max-width: 499px) {
|
||||
.studio_description {
|
||||
grid-column: 2;
|
||||
grid-row: 2/4;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.parc_description {
|
||||
grid-column: 6 / 8;
|
||||
grid-row: 1;
|
||||
z-index: 2;
|
||||
}
|
||||
@media (max-width: 799px) {
|
||||
.parc_description {
|
||||
grid-column: 2 / 5;
|
||||
grid-row: 2;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
@media (max-width: 499px) {
|
||||
.parc_description {
|
||||
grid-column: 2;
|
||||
grid-row: 6/8;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.banniere_pros--description {
|
||||
background-color: var(--c-background-blanc-casse);
|
||||
padding: 17px;
|
||||
max-height: 170px;
|
||||
&--titre {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
242
app/components/FilteredCards.vue
Normal file
242
app/components/FilteredCards.vue
Normal file
@@ -0,0 +1,242 @@
|
||||
<!-- Utilisé pour : -->
|
||||
<!-- Index.vue / Tous à l'orchestre -->
|
||||
|
||||
<!-- Permet de filtrer des contenus grâce à des boutons -->
|
||||
|
||||
<template>
|
||||
|
||||
<!-- FILTRES -->
|
||||
<SectionContent pad="xs" class="theme_tao--filters" role="tablist">
|
||||
<DsButton
|
||||
v-for="f in filters"
|
||||
:key="f.key"
|
||||
textColor="invert"
|
||||
size="aplati"
|
||||
borderColor="invert"
|
||||
:aria-pressed="activeFilter === f.key"
|
||||
:class="{ 'is-active': activeFilter === f.key }"
|
||||
@click="activeFilter = f.key"
|
||||
>
|
||||
{{ f.label }}
|
||||
</DsButton>
|
||||
</SectionContent>
|
||||
|
||||
<!-- CARTES HORIZONTALES -->
|
||||
<SectionContent class="theme_tao--cardlist">
|
||||
<HorizontalCards
|
||||
aria-label="Posts Instagram ONDIF"
|
||||
hint-key="tao-cardlist-hint-seen"
|
||||
:peek="30"
|
||||
:fade-width="64"
|
||||
:reset-key="activeFilter"
|
||||
reset-behavior="smooth"
|
||||
:reset-delay-ms="0"
|
||||
>
|
||||
|
||||
<DsCard
|
||||
v-for="card in filteredCards"
|
||||
:key="card.id"
|
||||
class="theme_tao--cardlist--card"
|
||||
>
|
||||
<div class="theme_tao--cardlist--card--wp">
|
||||
<!-- Image -->
|
||||
<div class="theme_tao--cardlist--card--img">
|
||||
<NuxtImg :src="card.imgSrc" :alt="card.imgAlt" />
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="theme_tao--cardlist--card--content">
|
||||
<DsHeading as="h5" tone="default">
|
||||
{{ card.title }}
|
||||
</DsHeading>
|
||||
|
||||
<DsText as="p" tone="default" :clamp="6">
|
||||
<span v-html="card.descriptionHtml" />
|
||||
</DsText>
|
||||
</div>
|
||||
</div>
|
||||
</DsCard>
|
||||
|
||||
</HorizontalCards>
|
||||
</SectionContent>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ref, computed, watch, nextTick } from 'vue'
|
||||
import DsCard from '@root/design-system/components/DsCard.vue'
|
||||
import DsHeading from '@root/design-system/primitives/DsHeading.vue'
|
||||
import DsButton from '@root/design-system/primitives/DsButton.vue'
|
||||
import SectionContent from '../components/section/SectionContent.vue'
|
||||
import DsText from '@root/design-system/primitives/DsText.vue'
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Filtres
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Variable qui contient les catégories qui permettront de filtrer
|
||||
const filters = [
|
||||
{ key: 'famille', label: 'Famille' },
|
||||
{ key: 'lieux', label: 'Lieux' },
|
||||
{ key: 'ateliers', label: 'Ateliers' },
|
||||
{ key: 'musique', label: 'Musique' },
|
||||
]
|
||||
// variable pour donner le filtre actif
|
||||
// filtre par défaut : le premier
|
||||
const activeFilter = ref(filters[0].key)
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// CONTENUS DES CARTES
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
const cards = ref([
|
||||
{
|
||||
id: 'insta-1',
|
||||
imgSrc: '/contenus/insta_ondif_1.jpg',
|
||||
imgAlt: 'le titre du post',
|
||||
title: "[Y'A PAS QUE LES ÂNES QUI MANGENT DU SON]",
|
||||
descriptionHtml: `Tu as moins de 28 ans ? Paie 6 € la place dès 3 concerts de l’Orchestre à la Philharmonie de Paris<br>
|
||||
🔴 Ile de France | Ministère de la culture<br>
|
||||
🎨 Agence belleville.eu`,
|
||||
tags: ['musique','famille'],
|
||||
},
|
||||
{
|
||||
id: 'insta-2',
|
||||
imgSrc: '/contenus/insta_ondif_2.jpg',
|
||||
imgAlt: 'le titre du post',
|
||||
title: "✨ Tous à l’orchestre ! Un début de saison qui fait vibrer l’Ondif 🎶",
|
||||
descriptionHtml: `Des lycéens conquis par Rachmaninov aux premières rencontres à Montereau, des petites oreilles émerveillées aux ateliers de Marly-la-Ville, sans oublier la musique portée jusqu'aux hôpitaux.<br>
|
||||
Et plus de 250 choristes rassemblés pour le "Chantons avec" Alice Swing !<br>
|
||||
Quelle énergie ❤️`,
|
||||
tags: ['famille', 'ateliers', 'musique', 'lieux'],
|
||||
},
|
||||
{
|
||||
id: 'insta-3',
|
||||
imgSrc: '/contenus/insta_ondif_3.jpg',
|
||||
imgAlt: 'le titre du post',
|
||||
title: "L'Orchestre en résidence à Montereau",
|
||||
descriptionHtml: `Notre équipe a rencontré les élèves de Montereau pour un premier atelier au Conservatoire municipal de musique Gaston Litaize`,
|
||||
tags: ['lieux', 'ateliers', 'famille'],
|
||||
},
|
||||
{
|
||||
id: 'insta-3',
|
||||
imgSrc: '/contenus/insta_ondif_3.jpg',
|
||||
imgAlt: 'le titre du post',
|
||||
title: "L'Orchestre en résidence à Montereau",
|
||||
descriptionHtml: `Notre équipe a rencontré les élèves de Montereau pour un premier atelier au Conservatoire municipal de musique Gaston Litaize`,
|
||||
tags: ['lieux', 'ateliers', 'famille'],
|
||||
},
|
||||
{
|
||||
id: 'insta-3',
|
||||
imgSrc: '/contenus/insta_ondif_3.jpg',
|
||||
imgAlt: 'le titre du post',
|
||||
title: "L'Orchestre en résidence à Montereau",
|
||||
descriptionHtml: `Notre équipe a rencontré les élèves de Montereau pour un premier atelier au Conservatoire municipal de musique Gaston Litaize`,
|
||||
tags: ['lieux', 'ateliers', 'famille'],
|
||||
},
|
||||
{
|
||||
id: 'insta-3',
|
||||
imgSrc: '/contenus/insta_ondif_3.jpg',
|
||||
imgAlt: 'le titre du post',
|
||||
title: "L'Orchestre en résidence à Montereau",
|
||||
descriptionHtml: `Notre équipe a rencontré les élèves de Montereau pour un premier atelier au Conservatoire municipal de musique Gaston Litaize`,
|
||||
tags: ['lieux', 'ateliers', 'famille'],
|
||||
},
|
||||
])
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Computed : cartes filtrées
|
||||
//--------------------------------------------------------------------------
|
||||
const filteredCards = computed(() => {
|
||||
return cards.value.filter(card =>
|
||||
card.tags.includes(activeFilter.value)
|
||||
)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
.theme_tao {
|
||||
margin-bottom: 50px;
|
||||
|
||||
&--description {
|
||||
max-width: 800px;
|
||||
}
|
||||
&--txt {
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
&--filters {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
column-gap: 10px;
|
||||
row-gap: 14px;
|
||||
.is-active {
|
||||
background-color: var(--c-surface);
|
||||
color: var(--c-backgroud-brandreverse);
|
||||
}
|
||||
}
|
||||
&--cardlist {
|
||||
margin-top: 20px;
|
||||
|
||||
&--card {
|
||||
background-color: var(--c-surface);
|
||||
border-radius: 10px;
|
||||
//padding: 50px;
|
||||
padding: clamp(18px, 2.4vw, 32px);
|
||||
|
||||
&--wp {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
&--img {
|
||||
max-width: 280px;
|
||||
overflow: hidden;
|
||||
img {
|
||||
max-height: 280px;
|
||||
}
|
||||
@media (min-width: 400px) {
|
||||
img {
|
||||
max-height: 350px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&--content {
|
||||
max-width: 320px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
}
|
||||
&--card {
|
||||
/* base: mobile-first */
|
||||
width: clamp(260px, 81vw, 360px);
|
||||
}
|
||||
@media (min-width: 400px) {
|
||||
&--card {
|
||||
width: clamp(260px, 80vw, 360px);
|
||||
}
|
||||
}
|
||||
@media (min-width: 500px) {
|
||||
&--card {
|
||||
width: clamp(280px, 63vw, 460px);
|
||||
}
|
||||
}
|
||||
@media (min-width: 700px) {
|
||||
&--card {
|
||||
width: clamp(280px, 60vw, 460px);
|
||||
}
|
||||
}
|
||||
@media (min-width: 1024px) {
|
||||
&--card {
|
||||
width: clamp(320px, 33vw, 520px);
|
||||
}
|
||||
}
|
||||
@media (min-width: 1440px) {
|
||||
&--card {
|
||||
width: clamp(360px, 28vw, 560px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<NewsletterCta />
|
||||
<PageSection tone="brand" :padded="false" content-size="default" padt="sm" padb="sm" class="footer">
|
||||
<PageSection tone="brand" content-size="default" padt="sm" padb="sm" class="footer">
|
||||
<div class="footer--inner">
|
||||
<SectionContent pad="xs" class="footer--logo">
|
||||
<NuxtImg :src="logoDefault" :alt="brand.logoAlt" class="logo-img" />
|
||||
@@ -26,19 +26,19 @@
|
||||
<div class="nav--item nav--social">
|
||||
|
||||
<a class="social" href="...">
|
||||
<NuxtImg :src="logoInstagram" alt="logo Instagram" height="37" width="37" class="social__icon" />
|
||||
<NuxtImg :src="logoInstagram" alt="logo Instagram" height="30" width="30" class="social__icon" />
|
||||
<span class="social__label">Instagram</span>
|
||||
</a>
|
||||
<a class="social" href="...">
|
||||
<NuxtImg :src="logoyt" alt="logo You Tube" height="28" width="37" class="social__icon" />
|
||||
<NuxtImg :src="logoyt" alt="logo You Tube" height="30" width="35" class="social__icon" />
|
||||
<span class="social__label">YouTube</span>
|
||||
</a>
|
||||
<a class="social" href="...">
|
||||
<NuxtImg :src="logofacebook" alt="logo Facebook" height="37" width="35" class="social__icon" />
|
||||
<NuxtImg :src="logofacebook" alt="logo Facebook" height="30" width="28" class="social__icon" />
|
||||
<span class="social__label">Facebook</span>
|
||||
</a>
|
||||
<a class="social" href="...">
|
||||
<NuxtImg :src="logolinkedin" alt="logo LinkedIn" height="37" width="37" class="social__icon" />
|
||||
<NuxtImg :src="logolinkedin" alt="logo LinkedIn" height="30" width="30" class="social__icon" />
|
||||
<span class="social__label">LinkedIn</span>
|
||||
</a>
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
</div>
|
||||
</PageSection>
|
||||
<PageSection :padded="false" content-size="default" padt="sm" padb="sm">
|
||||
<PageSection content-size="default" padt="sm" padb="sm">
|
||||
<SectionContent>
|
||||
<div class="footer_logos">
|
||||
<div><img class="footer_logos--img" :src="logoPrefet" height="80" alt="logo Préfet de la région d'Île-de-France" /></div>
|
||||
@@ -60,7 +60,7 @@
|
||||
</div>
|
||||
</SectionContent>
|
||||
</PageSection>
|
||||
<PageSection :padded="false" content-size="default" padt="sm" padb="sm">
|
||||
<PageSection content-size="default" padt="sm" padb="sm">
|
||||
<SectionContent>
|
||||
<div class="footer_mentions">
|
||||
<div class="footer_mentions--item">© Orchestre national d’Île-de-France - 2026</div>
|
||||
@@ -145,7 +145,7 @@
|
||||
display: block;
|
||||
padding: 4px;
|
||||
border-radius: 5px;
|
||||
background-color: rgb(255 255 255 / 83%);
|
||||
background-color: rgb(255 255 255 / 60%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
303
app/components/HorizontalCards.vue
Normal file
303
app/components/HorizontalCards.vue
Normal file
@@ -0,0 +1,303 @@
|
||||
<!-- app/components/HorizontalCards.vue -->
|
||||
<!-- Faire défiler des cartes qui se déplacent horizontalement -->
|
||||
<!-- Les cartes sont dans le composant qui appelle celui-çi, donc cela vaut pour tous types de cartes-->
|
||||
<template>
|
||||
<!-- Root: classe is-scrolled pour piloter fade + hint -->
|
||||
<div
|
||||
class="hc"
|
||||
:class="[
|
||||
rootClass,
|
||||
{ 'is-scrolled': hasScrolled }
|
||||
]"
|
||||
>
|
||||
<!-- Optional title slot -->
|
||||
<div v-if="$slots.title" class="hc__header">
|
||||
<slot name="title" />
|
||||
</div>
|
||||
|
||||
<!-- Hint icon (micro affordance) -->
|
||||
<div v-if="showHint" class="hc__hint" aria-hidden="true">
|
||||
<span class="hc__hint-icon">{{ hintIcon }}</span>
|
||||
</div>
|
||||
<div v-if="showHint" class="hc__hint--left" aria-hidden="true">
|
||||
<span class="hc__hint-icon">{{ hintIcon }}</span>
|
||||
</div>
|
||||
|
||||
<!-- Scroller -->
|
||||
<div
|
||||
ref="scroller"
|
||||
class="hc__scroller"
|
||||
:class="scrollerClass"
|
||||
tabindex="0"
|
||||
role="region"
|
||||
:aria-label="ariaLabel"
|
||||
@scroll.passive="onScroll"
|
||||
>
|
||||
<div class="hc__track" :class="trackClass">
|
||||
<!-- Cards -->
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, onBeforeUnmount, ref, computed, watch, nextTick } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
ariaLabel: { type: String, default: 'Horizontal content' },
|
||||
|
||||
/** Active l’animation "nudge" une seule fois (localStorage) */
|
||||
nudgeOnce: { type: Boolean, default: true },
|
||||
hintKey: { type: String, default: 'horizontal-cards-hint-seen' },
|
||||
|
||||
/** Nudge settings */
|
||||
nudgePx: { type: Number, default: 48 },
|
||||
nudgeDelayMs: { type: Number, default: 350 },
|
||||
nudgeReturnDelayMs: { type: Number, default: 450 },
|
||||
|
||||
/** UI affordances */
|
||||
showHint: { type: Boolean, default: true },
|
||||
hintIcon: { type: String, default: '⇆' },
|
||||
|
||||
/** Peek: % de padding-right du scroller pour montrer la carte suivante */
|
||||
peek: { type: Number, default: 30 }, // 25–40 conseillé
|
||||
|
||||
/** Fade (px) : largeur du dégradé */
|
||||
fadeWidth: { type: Number, default: 64 },
|
||||
|
||||
/** Classes hooks */
|
||||
rootClass: { type: [String, Array, Object], default: '' },
|
||||
scrollerClass: { type: [String, Array, Object], default: '' },
|
||||
trackClass: { type: [String, Array, Object], default: '' },
|
||||
|
||||
// Reset scroll (ex: changement de filtre)
|
||||
resetKey: { type: [String, Number], default: null },
|
||||
resetBehavior: { type: String, default: 'smooth' }, // 'smooth' ou 'auto'
|
||||
resetDelayMs: { type: Number, default: 0 },
|
||||
})
|
||||
|
||||
const scroller = ref(null)
|
||||
const hasScrolled = ref(false)
|
||||
|
||||
let t = null
|
||||
|
||||
const cssVars = computed(() => ({
|
||||
'--hc-peek': `${props.peek}%`,
|
||||
'--hc-fade-w': `${props.fadeWidth}px`
|
||||
}))
|
||||
|
||||
const markSeen = () => {
|
||||
try { localStorage.setItem(props.hintKey, '1') } catch (_) {}
|
||||
}
|
||||
const isSeen = () => {
|
||||
try { return localStorage.getItem(props.hintKey) === '1' } catch (_) { return true }
|
||||
}
|
||||
|
||||
const onScroll = () => {
|
||||
if (!hasScrolled.value) {
|
||||
hasScrolled.value = true
|
||||
markSeen()
|
||||
}
|
||||
if (t) clearTimeout(t)
|
||||
t = setTimeout(() => {}, 80)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const el = scroller.value
|
||||
if (!el) return
|
||||
|
||||
// Inject vars on root element
|
||||
// (Vue n’aime pas style binding + class binding sur le root via computed uniquement,
|
||||
// donc on set ici pour être sûr)
|
||||
el.closest('.hc')?.style?.setProperty('--hc-peek', `${props.peek}%`)
|
||||
el.closest('.hc')?.style?.setProperty('--hc-fade-w', `${props.fadeWidth}px`)
|
||||
|
||||
if (!props.nudgeOnce) return
|
||||
if (isSeen()) return
|
||||
|
||||
const reduce = window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches
|
||||
if (reduce) return
|
||||
|
||||
const canScroll = el.scrollWidth > el.clientWidth + 4
|
||||
if (!canScroll) return
|
||||
|
||||
setTimeout(() => {
|
||||
el.scrollBy({ left: props.nudgePx, behavior: 'smooth' })
|
||||
setTimeout(() => {
|
||||
el.scrollBy({ left: -props.nudgePx, behavior: 'smooth' })
|
||||
markSeen()
|
||||
}, props.nudgeReturnDelayMs)
|
||||
}, props.nudgeDelayMs)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (t) clearTimeout(t)
|
||||
})
|
||||
|
||||
// Pour revenir à la première carte sur changement de filtre
|
||||
const resetToStart = async () => {
|
||||
const el = scroller.value
|
||||
if (!el) return
|
||||
|
||||
await nextTick()
|
||||
|
||||
// Important : si tu changes le contenu + transition, un petit délai peut aider
|
||||
const run = () => el.scrollTo({ left: 0, behavior: props.resetBehavior })
|
||||
|
||||
if (props.resetDelayMs > 0) {
|
||||
setTimeout(run, props.resetDelayMs)
|
||||
} else {
|
||||
run()
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.resetKey,
|
||||
(nv, ov) => {
|
||||
// si c’est la première fois (ov === null) tu peux choisir de reset ou pas
|
||||
if (nv === ov) return
|
||||
resetToStart()
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* ==========================================================================
|
||||
HorizontalCards (no lib)
|
||||
- scroll-snap
|
||||
- peek (last card cut)
|
||||
- fade right
|
||||
- hint icon
|
||||
- nudge once (JS minimal)
|
||||
========================================================================== */
|
||||
|
||||
.hc {
|
||||
position: relative;
|
||||
|
||||
/* Vars (fallbacks) */
|
||||
--hc-peek: 30%;
|
||||
--hc-fade-w: 64px;
|
||||
}
|
||||
|
||||
/* Title slot */
|
||||
.hc__header {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
/* Hint icon */
|
||||
.hc__hint {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
box-shadow: 0 6px 18px rgba(0,0,0,0.12);
|
||||
opacity: 1;
|
||||
transition: opacity 180ms ease, transform 180ms ease;
|
||||
z-index: 2;
|
||||
}
|
||||
.hc__hint--left {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
box-shadow: 0 6px 18px rgba(0,0,0,0.12);
|
||||
opacity: 1;
|
||||
transition: opacity 180ms ease, transform 180ms ease;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.hc__hint-icon {
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* Scroller */
|
||||
.hc__scroller {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scroll-snap-type: x mandatory;
|
||||
|
||||
// Cacher la barre de défilement horizontal
|
||||
/* Firefox */
|
||||
scrollbar-width: none;
|
||||
/* IE / Edge legacy */
|
||||
-ms-overflow-style: none;
|
||||
/* WebKit (Chrome, Safari, Edge Chromium) */
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ✅ peek */
|
||||
padding: 0.25rem var(--hc-peek) 0.25rem 0;
|
||||
outline: none;
|
||||
|
||||
/* Fade right */
|
||||
&::after {
|
||||
content: '';
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: var(--hc-fade-w);
|
||||
height: 100%;
|
||||
|
||||
background: linear-gradient(
|
||||
to left,
|
||||
rgb(172 207 207 / 59%),
|
||||
rgba(172, 207, 207, 0)
|
||||
);
|
||||
opacity: 1;
|
||||
transition: opacity 180ms ease;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid currentColor;
|
||||
outline-offset: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Track */
|
||||
.hc__track {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
gap: 20px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
/* Snap + “rail-friendly” defaults for children */
|
||||
.hc__track > * {
|
||||
flex: 0 0 auto;
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* After first scroll: calm UI */
|
||||
.hc.is-scrolled {
|
||||
.hc__hint, .hc__hint--left {
|
||||
background: rgba(172, 207, 207, 0.9);
|
||||
//opacity: 0;
|
||||
transform: translateY(-50%) scale(0.96);
|
||||
}
|
||||
.hc__scroller::after {
|
||||
opacity: 0.55;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="newslettercta">
|
||||
<PageSection tone="brandreverse" :padded="false" content-size="default" padb="xs">
|
||||
<PageSection tone="brandreverse" content-size="default" padb="xs">
|
||||
<SectionTitle as="h1" tone="invert" pad="xs">
|
||||
NEWSLETTER
|
||||
</SectionTitle>
|
||||
@@ -42,10 +42,8 @@
|
||||
.newslettercta__content {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
|
||||
align-items: center;
|
||||
row-gap: 15px;
|
||||
column-gap: 15px;
|
||||
column-gap: 25px;
|
||||
padding-right: 10px;
|
||||
|
||||
.newslettercta__content_text {
|
||||
@@ -53,12 +51,18 @@
|
||||
}
|
||||
.newslettercta__button {
|
||||
grid-column: 1;
|
||||
justify-self: start;
|
||||
justify-self: center;
|
||||
}
|
||||
@media (min-width: 1000px) {
|
||||
.newslettercta__button {
|
||||
justify-self: center;
|
||||
margin-top: -10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (max-width: 300px) {
|
||||
.newslettercta__content {
|
||||
padding-left: calc(var(--section-title-pl, var(--sp-45)) - 20px);
|
||||
padding-left: calc(var(--sp-45) - 20px);
|
||||
}
|
||||
}
|
||||
@media (min-width: 500px) {
|
||||
|
||||
75
app/components/SquareCard.vue
Normal file
75
app/components/SquareCard.vue
Normal file
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<DsCard class="square-card">
|
||||
<div class="square-card__grid">
|
||||
<!-- Image -->
|
||||
<div class="square-card__media">
|
||||
<DsMedia :src="imgSrc" :alt="imgAlt" ratio="square" />
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="square-card__content">
|
||||
<DsHeading as="h5" tone="default" class="square-card__title">
|
||||
{{ title }}
|
||||
</DsHeading>
|
||||
<!-- Description -->
|
||||
<DsText as="p" tone="default" :clamp="3" class="square-card__description">
|
||||
{{ description }}
|
||||
</DsText>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</DsCard>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import DsCard from '@root/design-system/components/DsCard.vue'
|
||||
import DsMedia from '@root/design-system/primitives/DsMedia.vue'
|
||||
import DsHeading from '@root/design-system/primitives/DsHeading.vue'
|
||||
import DsText from '@root/design-system/primitives/DsText.vue'
|
||||
import DsButtonArrow from '@root/design-system/primitives/DsButtonArrow.vue'
|
||||
|
||||
|
||||
defineProps({
|
||||
id: { type: [String, Number], required: true },
|
||||
title: { type: String, required: true },
|
||||
url: { type: String, required: true },
|
||||
description: { type: String, default: '' },
|
||||
imgSrc: { type: String, default: '' },
|
||||
imgAlt: { type: String, default: '' },
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
.square-card__grid {
|
||||
display: grid;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.square-card__content {
|
||||
display: grid;
|
||||
gap: var(--sp-6);
|
||||
max-width: 518px;
|
||||
padding-left: 22px;
|
||||
padding-right: 20px;
|
||||
padding-top: 13px;
|
||||
padding-bottom: 10px;
|
||||
background: white;
|
||||
max-width: 85%;
|
||||
justify-self: center;
|
||||
position: relative;
|
||||
margin-top: -50px;
|
||||
}
|
||||
|
||||
.square-card__meta {
|
||||
margin-top: calc(var(--sp-4) * -1);
|
||||
}
|
||||
.square-card__description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.square-card__actions {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
</style>
|
||||
108
app/components/SquareCardList.vue
Normal file
108
app/components/SquareCardList.vue
Normal file
@@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<div class="square-card-list">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.square-card-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--gap-cards);
|
||||
justify-content: flex-start;
|
||||
}
|
||||
@media (max-width: 572px) {
|
||||
.square-card-list {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
// Afficher seulement 1 cards < 600px
|
||||
@media (max-width: 599px) {
|
||||
.square-card-list > .square-card:nth-child(2) {
|
||||
display: none;
|
||||
}
|
||||
.square-card-list > .square-card:nth-child(3) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Afficher seulement 2 cards < 900px
|
||||
@media (max-width: 799px) {
|
||||
.square-card-list > .square-card:nth-child(n+3) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Taille des cards
|
||||
@media (max-width: 599px) {
|
||||
.square-card-list > .square-card {
|
||||
max-width: 260px;
|
||||
flex: 1 1 260px;
|
||||
max-width: 90%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
.square-card-list > .square-card {
|
||||
max-width: 260px;
|
||||
flex: 1 1 260px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 700px) {
|
||||
.square-card-list > .square-card {
|
||||
max-width: 280px;
|
||||
flex: 1 1 280px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
.square-card-list > .square-card {
|
||||
max-width: 280px;
|
||||
flex: 1 1 280px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 900px) {
|
||||
.square-card-list > .square-card {
|
||||
max-width: 260px;
|
||||
flex: 1 1 260px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1000px) {
|
||||
.square-card-list > .square-card {
|
||||
max-width: 280px;
|
||||
flex: 1 1 280px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1100px) {
|
||||
.square-card-list > .square-card {
|
||||
max-width: 300px;
|
||||
flex: 1 1 300px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.square-card-list > .square-card {
|
||||
max-width: 258px;
|
||||
flex: 1 1 258px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1300px) {
|
||||
.square-card-list > .square-card {
|
||||
max-width: 283px;
|
||||
flex: 1 1 283px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1400px) {
|
||||
// style appliqué au composant enfant via sa classe
|
||||
.square-card-list > .square-card {
|
||||
max-width: 308px;
|
||||
flex: 1 1 308px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
74
app/components/TextCardLeft.vue
Normal file
74
app/components/TextCardLeft.vue
Normal file
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<DsCard class="textleft-card">
|
||||
<div class="textleft-card__grid">
|
||||
<!-- Content -->
|
||||
<div class="textleft-card__content">
|
||||
<DsHeading as="h5" tone="default" class="textleft-card__title">
|
||||
{{ title }}
|
||||
</DsHeading>
|
||||
<!-- Description -->
|
||||
<DsText as="p" tone="default" :clamp="3" class="textleft-card__description">
|
||||
{{ description }}
|
||||
</DsText>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="concert-card__actions">
|
||||
<DsButtonArrow :to="`/concerts/${id}`" variant="secondary">
|
||||
Découvrir
|
||||
</DsButtonArrow>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</DsCard>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import DsCard from '@root/design-system/components/DsCard.vue'
|
||||
import DsMedia from '@root/design-system/primitives/DsMedia.vue'
|
||||
import DsHeading from '@root/design-system/primitives/DsHeading.vue'
|
||||
import DsText from '@root/design-system/primitives/DsText.vue'
|
||||
import DsButtonArrow from '@root/design-system/primitives/DsButtonArrow.vue'
|
||||
|
||||
|
||||
defineProps({
|
||||
id: { type: [String, Number], required: true },
|
||||
title: { type: String, required: true },
|
||||
url: { type: String, required: true },
|
||||
description: { type: String, default: '' },
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
.textleft-card__grid {
|
||||
display: grid;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.textleft-card__content {
|
||||
display: grid;
|
||||
gap: var(--sp-6);
|
||||
max-width: 518px;
|
||||
padding-left: 10px;
|
||||
padding-right: 20px;
|
||||
padding-top: 3px;
|
||||
background: white;
|
||||
border-left: 2px solid;
|
||||
&:hover {
|
||||
border-left-color: var(--c-brand_rouge);
|
||||
}
|
||||
}
|
||||
|
||||
.textleft-card__meta {
|
||||
margin-top: calc(var(--sp-4) * -1);
|
||||
}
|
||||
.textleft-card__description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.textleft-card__actions {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
</style>
|
||||
108
app/components/TextCardLeftList.vue
Normal file
108
app/components/TextCardLeftList.vue
Normal file
@@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<div class="textleft-card-list">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.textleft-card-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--gap-cards);
|
||||
justify-content: flex-start;
|
||||
}
|
||||
@media (max-width: 572px) {
|
||||
.textleft-card-list {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
// Afficher seulement 1 cards < 600px
|
||||
@media (max-width: 599px) {
|
||||
.textleft-card-list > .textleft-card:nth-child(2) {
|
||||
display: none;
|
||||
}
|
||||
.textleft-card-list > .textleft-card:nth-child(3) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
// Afficher seulement 2 cards < 900px
|
||||
@media (max-width: 799px) {
|
||||
.textleft-card-list > .textleft-card:nth-child(3) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Taille des cards
|
||||
@media (max-width: 599px) {
|
||||
.textleft-card-list > .textleft-card {
|
||||
max-width: 260px;
|
||||
flex: 1 1 260px;
|
||||
max-width: 90%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 600px) {
|
||||
.textleft-card-list > .textleft-card {
|
||||
max-width: 247px;
|
||||
flex: 1 1 247px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 700px) {
|
||||
.textleft-card-list > .textleft-card {
|
||||
max-width: 280px;
|
||||
flex: 1 1 280px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
.textleft-card-list > .textleft-card {
|
||||
max-width: 231px;
|
||||
flex: 1 1 231px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 900px) {
|
||||
.textleft-card-list > .textleft-card {
|
||||
max-width: 258px;
|
||||
flex: 1 1 258px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1000px) {
|
||||
.textleft-card-list > .textleft-card {
|
||||
max-width: 288px;
|
||||
flex: 1 1 288px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1100px) {
|
||||
.textleft-card-list > .textleft-card {
|
||||
max-width: 311px;
|
||||
flex: 1 1 311px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.textleft-card-list > .textleft-card {
|
||||
max-width: 334px;
|
||||
flex: 1 1 334px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1300px) {
|
||||
.textleft-card-list > .textleft-card {
|
||||
max-width: 367px;
|
||||
flex: 1 1 367px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1400px) {
|
||||
// style appliqué au composant enfant via sa classe
|
||||
.textleft-card-list > .textleft-card {
|
||||
max-width: 400px;
|
||||
flex: 1 1 400px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
@@ -1,11 +1,10 @@
|
||||
<script setup>
|
||||
import logoDefault from '/img/logos/logo_orchestre_red.svg'
|
||||
import agendaRouge from '@/assets/img/icones/agenda_rouge.svg'
|
||||
import ticket from '@/assets/img/icones/ticket_black.svg'
|
||||
import mobile_agenda_icon from '@/assets/img/icones/agenda_rouge_fonce_blanc.svg'
|
||||
import mobile_ticket from '@/assets/img/icones/ticket_white.svg'
|
||||
import ticket from '@/assets/img/icones/ticket_noir.svg'
|
||||
import mobile_agenda_icon from '@/assets/img/icones/agenda_blanc_non_opaque.svg'
|
||||
import mobile_ticket from '@/assets/img/icones/ticket_blanc.svg'
|
||||
const { brand } = useAppConfig()
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -18,17 +17,31 @@
|
||||
<img :src="agendaRouge" alt="icone agenda" />
|
||||
</template>
|
||||
<template #ticket>
|
||||
<img class="img_ticket" :src="ticket" alt="icone ticket" />
|
||||
<img class="img_ticket_desktop" :src="ticket" alt="icone ticket" />
|
||||
</template>
|
||||
<template #mobile_agenda_icon>
|
||||
<img :src="mobile_agenda_icon" alt="icone ticket" />
|
||||
</template>
|
||||
|
||||
<template #mobile_ticket>
|
||||
<img :src="mobile_ticket" alt="icone ticket" />
|
||||
<img class="img_ticket_mob" :src="mobile_ticket" alt="icone ticket" />
|
||||
</template>
|
||||
|
||||
</HeaderNav>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
.img_ticket_desktop {
|
||||
max-height: 26px;
|
||||
margin-top: 4px;
|
||||
margin-left: -11px;
|
||||
}
|
||||
.img_ticket_mob {
|
||||
max-height: 37px;
|
||||
margin-top: 9px;
|
||||
margin-left: -11px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
@@ -32,7 +32,7 @@
|
||||
<nav class="header_nav_cont" aria-label="Primary navigation">
|
||||
<!-- Desktop nav -->
|
||||
<ul class="header_nav header_nav--desktop">
|
||||
<li class="header_nav_item brandontext_bold">
|
||||
<li class="header_nav_item">
|
||||
L'Orchestre
|
||||
<ul class="header_nav_sub_menu">
|
||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Nos missions</NuxtLink></li>
|
||||
@@ -56,7 +56,7 @@
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="header_nav_item brandontext_bold">
|
||||
<li class="header_nav_item">
|
||||
Éducation et médiation
|
||||
<ul class="header_nav_sub_menu">
|
||||
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Petite enfance</NuxtLink></li>
|
||||
@@ -156,7 +156,7 @@
|
||||
>
|
||||
<ul class="header_drawer_inner">
|
||||
<li
|
||||
class="header_drawer_link brandontext_bold"
|
||||
class="header_drawer_link"
|
||||
:class="{ 'is-open': activeDrawer === 'orchestre' }"
|
||||
@click="toggleDrawer('orchestre')"
|
||||
>
|
||||
@@ -188,7 +188,7 @@
|
||||
</li>
|
||||
|
||||
<li
|
||||
class="header_drawer_link brandontext_bold"
|
||||
class="header_drawer_link"
|
||||
:class="{ 'is-open': activeDrawer === 'education' }"
|
||||
@click="toggleDrawer('education')"
|
||||
>
|
||||
@@ -217,15 +217,17 @@
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<NuxtLink class="header_drawer_link icon_mobile_agenda" to="/agenda" @click="close">
|
||||
<!-- ICÔNE injectée -->
|
||||
<slot name="mobile_agenda_icon" />
|
||||
</NuxtLink>
|
||||
|
||||
<NuxtLink class="header_drawer_link icon_mobile_ticket" to="/agenda" @click="close">
|
||||
<!-- ICÔNE injectée -->
|
||||
<slot name="mobile_ticket" />
|
||||
</NuxtLink>
|
||||
<li class="icon_mobile">
|
||||
<NuxtLink class="header_drawer_link icon_mobile_agenda" to="/agenda" @click="close">
|
||||
<!-- ICÔNE injectée -->
|
||||
<slot name="mobile_agenda_icon" />
|
||||
</NuxtLink>
|
||||
<NuxtLink class="header_drawer_link icon_mobile_ticket" to="/agenda" @click="close">
|
||||
<!-- ICÔNE injectée -->
|
||||
<slot name="mobile_ticket" />
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -262,6 +264,12 @@
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
.icon_mobile {
|
||||
display: flex;
|
||||
column-gap: 20px;
|
||||
padding-left: 3px;
|
||||
}
|
||||
.icon_mobile_agenda {
|
||||
width: 35px;
|
||||
margin-top: 10px;
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
<template>
|
||||
<header>
|
||||
<div class="bg-orbs" aria-hidden="true">
|
||||
<span class="orb orb--1" />
|
||||
<span class="orb orb--2" />
|
||||
<span class="orb orb--3" />
|
||||
<span class="orb orb--4" />
|
||||
<span class="orb orb--5" />
|
||||
<span class="orb orb--6" />
|
||||
<!-- <span class="orb orb--1" /> -->
|
||||
<!-- <span class="orb orb--2" /> -->
|
||||
<!-- <span class="orb orb--3" /> -->
|
||||
<!-- <span class="orb orb--4" /> -->
|
||||
<!-- <span class="orb orb--5" /> -->
|
||||
<!-- <span class="orb orb--6" /> -->
|
||||
</div>
|
||||
<div class="header_layout" :class="`header--${theme}`">
|
||||
<slot />
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
<section
|
||||
class="page-section"
|
||||
:class="[
|
||||
`page-section--overflow--${overflow}`,
|
||||
`page-section--${tone}`,
|
||||
{ 'page-section--padded': padded }
|
||||
{ 'page-section--padded': padded },
|
||||
`page-section--padded--${padded_size}`
|
||||
]"
|
||||
>
|
||||
<!-- Si content == true -->
|
||||
<PageSectionInner v-if="content" :size="contentSize" :padt="padt" :padb="padb">
|
||||
<PageSectionInner v-if="content" :size="contentSize" :padt="padt" :padb="padb" :position="position" :overflow="overflow">
|
||||
<slot />
|
||||
</PageSectionInner>
|
||||
|
||||
@@ -28,11 +30,13 @@
|
||||
<script setup>
|
||||
defineProps({
|
||||
tone: { type: String, default: 'default' }, // default / brand / muted / dark…
|
||||
padded: { type: Boolean, default: true }, // padding vertical
|
||||
padded_size: { type: String, default: '' }, // none | sm | md | lg
|
||||
contentSize: { type: String, default: 'default'}, // narrow/default/wide
|
||||
content: { type: Boolean, default: true }, // contenu contraint ou full
|
||||
padb : { type: String, default: '' }, // props pour PageSectionInner
|
||||
padt : { type: String, default: '' } // props pour PageSectionInner
|
||||
padt : { type: String, default: '' }, // props pour PageSectionInner
|
||||
position : { type: String, default: '' },
|
||||
overflow : { type: String, default: '' }
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -41,6 +45,9 @@
|
||||
position: relative;
|
||||
width: 100%;
|
||||
//min-height: var(--sp-200);
|
||||
&--overflow--hidden {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* tons = arrière-plan section */
|
||||
&--default { background: transparent; }
|
||||
@@ -50,8 +57,14 @@
|
||||
|
||||
// padding en haut et en bas
|
||||
&--padded {
|
||||
padding-top: 30px;
|
||||
padding-bottom: 50px;
|
||||
&--md {
|
||||
padding-top: 30px;
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
&--lg {
|
||||
padding-top: 30px;
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Des templates peuvent avoir toutes la même marge de page et d'autres, par ex, être full page -->
|
||||
|
||||
<template>
|
||||
<div class="page-section--inner" :class="[`page-section--inner--${size}`,`page-section--inner--padb--${padb}`,`page-section--inner--padt--${padt}`]">
|
||||
<div class="page-section--inner" :class="[`page-section--inner--${size}`,`page-section--inner--padb--${padb}`,`page-section--inner--padt--${padt}`,`page-section--inner--position--${position}`,`page-section--inner--overflow--${overflow}`]">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
@@ -11,7 +11,8 @@
|
||||
defineProps({
|
||||
size: { type: String, default: 'default' }, // default / wide / narrow
|
||||
padb : { type: String, default: '' },
|
||||
padt : { type: String, default: '' }
|
||||
padt : { type: String, default: '' },
|
||||
position : { type: String, dafault : ''}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -25,7 +26,9 @@
|
||||
|
||||
// respiration sur les côtés avec marges minimale ( surtout utile pour mobiles)
|
||||
|
||||
|
||||
&--position--relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
// limite de largeur quand on veut une largeur plus petit (pour les articles par exemple)
|
||||
&--narrow {
|
||||
@@ -37,7 +40,7 @@
|
||||
/* mobile / small screens */
|
||||
|
||||
@media (max-width: 700px) {
|
||||
padding-inline: var(--page-padding-mobile);
|
||||
//padding-inline: var(--page-padding-mobile);
|
||||
}
|
||||
|
||||
@media (min-width: 0px) {
|
||||
|
||||
@@ -29,30 +29,44 @@
|
||||
&--tone-brandreverse { background: var(--c-backgroud-brandreverse); }
|
||||
|
||||
&--pad-xs {
|
||||
padding-top: var(--sp-32);
|
||||
//padding-top: var(--sp-32);
|
||||
padding-bottom: var(--sp-16);
|
||||
padding-left: var(--sp-45);
|
||||
padding-right: var(--sp-8);
|
||||
}
|
||||
&--pad-sm {
|
||||
padding-top: var(--sp-32);
|
||||
//padding-top: var(--sp-32);
|
||||
padding-bottom: var(--sp-16);
|
||||
padding-left: var(--sp-45);
|
||||
padding-right: var(--sp-8);
|
||||
}
|
||||
&--pad-md {
|
||||
padding-top: var(--sp-80);
|
||||
//padding-top: var(--sp-80);
|
||||
padding-bottom: var(--sp-180);
|
||||
padding-left: var(--sp-45);
|
||||
padding-right: var(--sp-8);
|
||||
}
|
||||
&--pad-lg {
|
||||
padding-top: var(--sp-80);
|
||||
//padding-top: var(--sp-80);
|
||||
padding-bottom: var(--sp-180);
|
||||
padding-left: var(--sp-45);
|
||||
padding-right: var(--sp-8);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 400px) {
|
||||
.section-content {
|
||||
&--pad-xs {
|
||||
//padding-bottom: calc(var(--sp-16) * 0.5);
|
||||
padding-left: calc(var(--sp-45) * 0.5);
|
||||
//padding-right: calc(var(--sp-8) * 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 300px) {
|
||||
.section-title {
|
||||
padding-left: calc(var(--section-title-pl, var(--sp-45)) - 20px);
|
||||
padding-left: calc(var(--sp-45) - 20px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,10 +45,17 @@
|
||||
padding-left: var(--sp-45);
|
||||
}
|
||||
}
|
||||
@media (max-width: 400px) {
|
||||
.section-title {
|
||||
&--pad-xs {
|
||||
padding-left: calc(var(--sp-45) * 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 300px) {
|
||||
.section-title {
|
||||
padding-left: calc(var(--section-title-pl, var(--sp-45)) - 20px);
|
||||
padding-left: calc(var(--sp-45) - 20px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user