update a lot of change since a while

This commit is contained in:
2026-01-22 10:29:36 +01:00
parent a4dcb95d83
commit e1c1475f10
78 changed files with 4200 additions and 534 deletions

193
app/components/Footer.vue Normal file
View File

@@ -0,0 +1,193 @@
<template>
<NewsletterCta />
<PageSection tone="brand" :padded="false" 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" />
</SectionContent>
<SectionContent pad="xs">
<div class="footer--grid">
<div class="footer--grid--orchestre">
<div class="nav--item">L'équipe</div>
<div class="nav--item">Nous contacter</div>
</div>
<div class="footer--grid--nav1">
<div class="nav--title">Nous soutenir</div>
<div class="nav--item">Mécénat</div>
<div class="nav--item">XXXX</div>
</div>
<div class="footer--grid--nav2">
<div class="nav--title">Rejoignez-nous</div>
<div class="nav--item">Recrutement</div>
<div class="nav--item">Académie d'Orchestre</div>
</div>
<div class="footer--grid--social">
<div class="nav--title">Nos réseaux</div>
<div class="nav--item nav--social">
<a class="social" href="...">
<NuxtImg :src="logoInstagram" alt="logo Instagram" height="37" width="37" 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" />
<span class="social__label">YouTube</span>
</a>
<a class="social" href="...">
<NuxtImg :src="logofacebook" alt="logo Facebook" height="37" width="35" 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" />
<span class="social__label">LinkedIn</span>
</a>
</div>
</div>
</div>
</SectionContent pad="xs">
</div>
</PageSection>
<PageSection :padded="false" 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>
<div><img class="footer_logos--img" :src="logoIdf" height="80" alt="logo Région Île-de-France" /></div>
<div><img class="footer_logos--img" :src="logoParis" height="80" alt="logo Région Paris" /></div>
</div>
</SectionContent>
</PageSection>
<PageSection :padded="false" 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>
<div class="footer_mentions--item">Conditions générales de vente</div>
<div class="footer_mentions--item">Mentions légales</div>
</div>
</SectionContent>
</PageSection>
</template>
<script setup>
import logoDefault from '/img/logos/logo_orchestre_red.svg'
import logoInstagram from '/img/icones/instagram_gradient.svg'
import logoyt from '/img/icones/youtube_play_rouge.svg'
import logofacebook from '/img/icones/facebook_rond_bleu.svg'
import logolinkedin from '/img/icones/linkedin_bleu.png'
import logoPrefet from '@/assets/img/logos/logo_pref_idf.webp'
import logoIdf from '@/assets/img/logos/logo_region_idf.webp'
import logoParis from '@/assets/img/logos/logo_region_paris.webp'
const { brand } = useAppConfig()
</script>
<style lang="scss">
.footer {
color: var(--c-text-invert);
font-family: var(--font-roboto);
font-weight: var(--fw-extralight);
&--logo {
max-width: 250px;
img {
filter: invert(100%) sepia(96%) saturate(18%) hue-rotate(237deg) brightness(127%) contrast(105%);
}
}
&--grid {
display: grid;
@media (max-width: 400px) {
grid-template-columns: 1fr;
row-gap: 20px;
}
@media (min-width: 400px) {
grid-template-columns: 1fr 1fr;
column-gap: 30px;
row-gap: 40px;
}
@media (min-width: 900px) {
grid-template-columns: 1.2fr 1fr 1fr 1fr;
column-gap: 50px;
row-gap: 50px;
}
align-items: start;
margin-top: 20px;
}
.nav {
&--title {
padding-bottom: 12px;
font-weight: var(--fw-black);
}
&--item {
padding-bottom: 6px;
}
&--social {
display: grid;
grid-template-columns: max-content max-content;
column-gap: 5px;
row-gap: 6px;
align-items: center;
.social {
display: contents;
&__icon {
display: block;
padding: 4px;
border-radius: 5px;
background-color: rgb(255 255 255 / 83%);
}
}
}
}
}
.footer_logos {
display: flex;
flex-wrap: wrap;
justify-content: center;
column-gap: 15px;
row-gap: 20px;
&--img {
object-fit: contain;
max-height: 70px;
@media (max-width: 300px) {
max-width: 210px;
}
@media (min-width: 300px) {
max-width: 290px;
}
@media (min-width: 400px) {
max-width: 390px;
}
@media (min-width: 900px) {
max-width: 390px;
}
}
}
.footer_mentions {
display: flex;
flex-wrap: wrap;
justify-content: center;
column-gap: 15px;
row-gap: 12px;
font-family: var(--font-roboto);
font-weight: var(--fw-medium);
font-size: 12px;
}
</style>

View File

@@ -0,0 +1,73 @@
<template>
<div class="newslettercta">
<PageSection tone="brandreverse" :padded="false" content-size="default" padb="xs">
<SectionTitle as="h1" tone="invert" pad="xs">
NEWSLETTER
</SectionTitle>
<SectionContent pad="xs" class="newslettercta__content">
<div class="newslettercta__content_text">
<DsText as="p" tone="invert">
Recevez l'actualité des concerts de l'Orchestre national d'Île-de-France par infolettre !
</DsText>
</div>
<div class="newslettercta__button">
<DsButton
href="https://eb686efa.sibforms.com/serve/MUIFAP2a1WdNgM9e0cv4B5b_QwHC_QzCXtnwSoUEWllWVV1Kxq7vbzbRVWoIagXviq-jYQHuKv0-AN8cmEggeJnUds8C4VumwkC0dCTD0kQPVZ8nXWhXG5ABFo4EEys6OY-C_qQW4iUnWeq8cFA8X3dRaLj_q410BX_yvp6E8o5eOklPWsKkZnmXI1Qc31WqegQhTTkp_Z0Jhbg="
target="_blank"
rel="noopener noreferrer"
textColor="invert"
borderColor="invert"
>
Restez informé
</DsButton>
</div>
</SectionContent>
</PageSection>
</div>
</template>
<script setup>
import DsText from '@root/design-system/primitives/DsText.vue'
import DsButton from '@root/design-system/primitives/DsButton.vue'
</script>
<style lang="scss">
.newslettercta {
margin-bottom: 30px;
}
.newslettercta__content {
display: grid;
grid-template-columns: minmax(0, 1fr);
align-items: center;
row-gap: 15px;
column-gap: 15px;
padding-right: 10px;
.newslettercta__content_text {
grid-column: 1;
}
.newslettercta__button {
grid-column: 1;
justify-self: start;
}
}
@media (max-width: 300px) {
.newslettercta__content {
padding-left: calc(var(--section-title-pl, var(--sp-45)) - 20px);
}
}
@media (min-width: 500px) {
.newslettercta__content {
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
.newslettercta__button {
grid-column: 2;
}
}
}
</style>

View File

@@ -1,30 +0,0 @@
<template>
<NuxtLink :to="to" :class="['btn', variantClass]">
<slot />
</NuxtLink>
</template>
<script setup>
// defineProps() sert à déclarer les propriétés (props) que ton composant peut recevoir depuis lextérieur.
// “Ce composant attend certains paramètres quon lui passera.”
const props = defineProps({
to: {
type: String,
required: true
},
variant: {
type: String,
default: 'primary'
}
})
// la fonction computed sert a se synchroniser chaque fois que la props variant change, ce rend dynamique la mise à jour de la variable, cela s'appelle une propriété calculée
const variantClass = computed(() => {
return `btn--${props.variant}`
})
</script>
<style>
</style>

View File

@@ -0,0 +1,88 @@
<template>
<DsCard class="concert-card">
<div class="concert-card__grid">
<!-- Image -->
<div class="concert-card__media">
<DsMedia :src="imageUrl" :alt="imageAlt" ratio="square" />
</div>
<!-- Content -->
<div class="concert-card__content">
<DsHeading as="h4" tone="default" class="concert-card__title">
{{ title }}
</DsHeading>
<!-- Meta : date + lieu -->
<div class="concert-card__meta">
<DsHeading as="h5" tone="default">
{{ venue }}
</DsHeading>
<DsHeading as="h6" tone="default">
<time :datetime="dateISO">{{ dateLabel }}</time>
</DsHeading>
</div>
<!-- Description -->
<DsText as="p" tone="default" :clamp="3" class="concert-card__description">
{{ description }}
</DsText>
<!-- Actions -->
<div class="concert-card__actions">
<DsButtonArrow :to="`/concerts/${id}`" variant="secondary">
Réserver
</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 },
venue: { type: String, required: true },
dateISO: { type: String, required: true }, // ex: "2026-01-15T20:00:00+01:00"
dateLabel: { type: String, required: true }, // ex: "Jeu. 15 jan. 2026 — 20h"
description: { type: String, default: '' },
imageUrl: { type: String, default: '' },
imageAlt: { type: String, default: '' },
})
</script>
<style lang="scss">
.concert-card__grid {
display: grid;
gap: var(--sp-16);
align-items: start;
}
.concert-card__content {
display: grid;
gap: var(--sp-6);
max-width: 518px;
padding-left: 5px;
padding-right: 5px;
}
.concert-card__meta {
margin-top: calc(var(--sp-4) * -1);
}
.concert-card__description {
margin-top: 10px;
margin-bottom: 20px;
}
.concert-card__actions {
margin-top: auto;
}
</style>

View File

@@ -0,0 +1,126 @@
<template>
<div class="concert-card-list">
<slot />
</div>
</template>
<style lang="scss">
.concert-card-list {
display: flex;
flex-wrap: wrap;
gap: var(--gap-cards);
justify-content: center;
}
// Afficher seulement 1 cards < 600px
@media (max-width: 599px) {
.concert-card-list > .concert-card:nth-child(2) {
display: none;
}
.concert-card-list > .concert-card:nth-child(3) {
display: none;
}
}
// Afficher seulement 2 cards < 900px
@media (max-width: 899px) {
.concert-card-list > .concert-card:nth-child(3) {
display: none;
}
}
// Taille des cards
@media (max-width: 599px) {
.concert-card-list > .concert-card {
flex: 1 1 260px;
max-width: 90%;
}
}
@media (min-width: 600px) {
.concert-card-list > .concert-card {
flex: 1 1 260px;
}
.concert-card-list > .concert-card:first-child {
flex: 2 1 280px;
}
}
@media (min-width: 700px) {
.concert-card-list > .concert-card {
flex: 1 1 280px;
}
.concert-card-list > .concert-card:first-child {
flex: 2 1 300px;
}
}
@media (min-width: 800px) {
.concert-card-list > .concert-card {
flex: 1 1 280px;
}
.concert-card-list > .concert-card:first-child {
flex: 2 1 300px;
}
}
@media (min-width: 900px) {
.concert-card-list > .concert-card {
flex: 1 1 260px;
}
.concert-card-list > .concert-card:first-child {
flex: 2 1 300px;
}
}
@media (min-width: 1000px) {
.concert-card-list > .concert-card {
flex: 1 1 280px;
}
.concert-card-list > .concert-card:first-child {
flex: 2 1 340px;
}
}
@media (min-width: 1100px) {
.concert-card-list > .concert-card {
flex: 1 1 300px;
}
.concert-card-list > .concert-card:first-child {
flex: 2 1 380px;
}
}
@media (min-width: 1200px) {
.concert-card-list > .concert-card {
flex: 1 1 320px;
}
.concert-card-list > .concert-card:first-child {
flex: 2 1 400px;
}
}
@media (min-width: 1300px) {
.concert-card-list > .concert-card {
flex: 1 1 340px;
}
.concert-card-list > .concert-card:first-child {
flex: 2 1 440px;
}
}
@media (min-width: 1400px) {
// style appliqué au composant enfant via sa classe
.concert-card-list > .concert-card {
flex: 1 1 360px;
}
//règle spécifique après la règle générale
.concert-card-list > .concert-card:first-child {
flex: 2 1 480px;
}
}
</style>

View File

@@ -0,0 +1,13 @@
<script setup>
defineProps({
burgerColor: { type: String, default: 'hamburger_black' }
})
</script>
<template>
<span class="burger">
<span :class="['burger_line', burgerColor]"></span>
<span :class="['burger_line', burgerColor]"></span>
<span :class="['burger_line', burgerColor]"></span>
</span>
</template>

View File

@@ -0,0 +1,34 @@
<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'
const { brand } = useAppConfig()
</script>
<template>
<HeaderNav burger-color="hamburger_black">
<template #logo>
<NuxtImg :src="logoDefault" :alt="brand.logoAlt" class="logo-img" />
</template>
<template #agenda-icon>
<img :src="agendaRouge" alt="icone agenda" />
</template>
<template #ticket>
<img class="img_ticket" :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" />
</template>
</HeaderNav>
</template>
<style lang="scss">
</style>

View File

@@ -0,0 +1,57 @@
<script setup>
import logoFull from '/img/logos/logo_blanc_rouge.png'
import agendaNoir from '@/assets/img/icones/agenda_rouge_fonce_blanc.svg'
import ticket from '@/assets/img/icones/ticket_white.svg'
import mobile_agenda_icon from '@/assets/img/icones/agenda_rouge_fonce_blanc.svg'
import mobile_ticket from '@/assets/img/icones/ticket_white.svg'
const { brand } = useAppConfig()
</script>
<template>
<HeaderNav burger-color="hamburger_white">
<template #logo>
<NuxtImg :src="logoFull" :alt="brand.logoAlt" class="logo-img" />
</template>
<template #agenda-icon>
<img :src="agendaNoir" alt="icone agenda" />
</template>
<template #ticket>
<img :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" />
</template>
</HeaderNav>
<div class="obscur"></div>
<div class="header-img_cont">
<NuxtImg
src="/img/photos/zaho.jpg"
placeholder
preset="full"
alt="L'orchestre National d'Île-de-france en concert - vue d'ensemble"
class="header-img"
/>
</div>
<div class="header-img_text">
<div class="header-img_titre">ZAHO DE SAGAZAN</div>
<div class="header-img_description">Accompagnée par lOrchestre national dÎle-de-France dirigé par Dylan Corlay, Zaho de Sagazan revisite les chansons de son premier album pour les plonger dans une toute nouvelle dimension !</div>
<div class="decouvrir"><div class="decouvrir_icone"><img src="@/assets/img/icones/fleche_gris_blanc.svg" alt="icone flèche"></div><div class="decouvrir_texte">Découvrir</div></div>
</div>
</template>

View File

@@ -0,0 +1,278 @@
<template>
<div class="header_navigation">
<div class="height_10"></div>
<ul class="header_navigation_topbar" aria-label="Language selector">
<li class="header_nav_topbar_item">
Professionnels
<ul class="header_nav_topbar_submenu">
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Programmer l'Orchestre</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Le studio et les espaces</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Louer des instruments</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Recrutement / Concours</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Espace candidats</NuxtLink></li>
<li class="header_nav_topbar_submenu_item"><NuxtLink to="/">Presse</NuxtLink></li>
</ul>
</li>
<li class="header_nav_topbar_item header_nav_lang">
<div class="header_nav_lang_item">FR</div>
<div class="header_nav_lang_item">/</div>
<div class="header_nav_lang_item">EN</div>
</li>
</ul>
<div class="height_20"></div>
<div class="header_navigation_main">
<div class="header_nav_logo">
<!-- LOGO injecté -->
<slot name="logo" />
</div>
<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">
L'Orchestre
<ul class="header_nav_sub_menu">
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Nos missions</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Direction musicale</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Les musiciens</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Les artistes invités</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Discographie</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Nos partenaires</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Nous soutenir</NuxtLink></li>
</ul>
</li>
<li class="header_nav_item">
Concerts
<ul class="header_nav_sub_menu">
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Saison</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Jeune public</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Concert mode d'emploi</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">ONDIF MAG</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">ONDIF LIVE !</NuxtLink></li>
</ul>
</li>
<li class="header_nav_item brandontext_bold">
Éducation et médiation
<ul class="header_nav_sub_menu">
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Petite enfance</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Scolaires</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Champ social</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Insertion professionnelle</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Pratiques amateurs</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Ressources pédagogiques</NuxtLink></li>
</ul>
</li>
<li class="header_nav_item">
Mécénat
<ul class="header_nav_sub_menu">
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Entreprises</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Les projets</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Particuliers</NuxtLink></li>
<li class="header_nav_sub_menu_item"><NuxtLink to="/">Ils nous font confiance</NuxtLink></li>
</ul>
</li>
<li class="header_nav_item header_nav_icones">
<div class="">
<NuxtLink to="/agenda">
<div class="nav_icone">
<div class="nav_icone_img nav_icone_img--agenda">
<!-- ICÔNE injectée -->
<span class="sr-only">Agenda</span>
<slot name="agenda-icon" />
</div>
</div>
</NuxtLink>
</div>
<div class=" padding_top_1">
<NuxtLink to="/agenda">
<div class="nav_icone">
<div class="nav_icone_img nav_icone_img--ticket">
<!-- ICÔNE injectée -->
<span class="sr-only">billeterie</span>
<slot name="ticket" />
</div>
</div>
</NuxtLink>
</div>
</li>
</ul>
<!-- Mobile nav -->
<div class="header_nav--mobile">
<button
class="header_burger"
type="button"
:class="{ 'is-open': isOpen }"
:aria-expanded="isOpen ? 'true' : 'false'"
aria-controls="mobile-menu"
@click="toggle"
>
<span class="sr-only">{{ isOpen ? 'Fermer le menu' : 'Ouvrir le menu' }}</span>
<!-- icone hamburger injecté -->
<BurgerIcon :burger-color="burgerColor" />
</button>
</div>
<!-- Mobile icons -->
<div class="header_nav header_nav--mobile-icons">
<div class="header_nav_item">
<NuxtLink to="/agenda">
<div class="nav_icone">
<div class="nav_icone_img nav_icone_img--agenda">
<!-- ICÔNE injectée -->
<span class="sr-only">Agenda</span>
<slot name="agenda-icon" />
</div>
</div>
</NuxtLink>
</div>
<div class="header_nav_item padding_top_1">
<NuxtLink to="/agenda">
<div class="nav_icone">
<div class="nav_icone_img nav_icone_img--ticket">
<!-- ICÔNE injectée -->
<span class="sr-only">billeterie</span>
<slot name="ticket" />
</div>
</div>
</NuxtLink>
</div>
</div>
<!-- Mobile drawer -->
<div
id="mobile-menu"
class="header_drawer"
:data-open="isOpen ? 'true' : 'false'"
>
<ul class="header_drawer_inner">
<li
class="header_drawer_link brandontext_bold"
:class="{ 'is-open': activeDrawer === 'orchestre' }"
@click="toggleDrawer('orchestre')"
>
L'Orchestre
<ul class="header_drawer_sub_menu">
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Nos missions</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Direction musicale</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Les musiciens</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Les artistes invités</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Discographie</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Nos partenaires</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Nous soutenir</NuxtLink></li>
</ul>
</li>
<li
class="header_drawer_link"
:class="{ 'is-open': activeDrawer === 'concerts' }"
@click="toggleDrawer('concerts')"
>
Concerts
<ul class="header_drawer_sub_menu">
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Saison</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Jeune public</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Concert mode d'emploi</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">ONDIF MAG</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">ONDIF LIVE !</NuxtLink></li>
</ul>
</li>
<li
class="header_drawer_link brandontext_bold"
:class="{ 'is-open': activeDrawer === 'education' }"
@click="toggleDrawer('education')"
>
Éducation et médiation
<ul class="header_drawer_sub_menu">
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Petite enfance</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Scolaires</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Champ social</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Insertion professionnelle</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Pratiques amateurs</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Ressources pédagogiques</NuxtLink></li>
</ul>
</li>
<li
class="header_drawer_link"
:class="{ 'is-open': activeDrawer === 'mecenat' }"
@click="toggleDrawer('mecenat')"
>
Mécénat
<ul class="header_drawer_sub_menu">
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Entreprises</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Les projets</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Particuliers</NuxtLink></li>
<li class="header_drawer_sub_menu_item"><NuxtLink to="/">Ils nous font confiance</NuxtLink></li>
</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>
</ul>
</div>
</nav>
</div>
<div class="height_25"></div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRoute } from 'vue-router'
import { watch } from 'vue'
defineProps({
burgerColor: { type: String, default: 'hamburger_black' }
})
const isOpen = ref(false)
const activeDrawer = ref(null)
const toggle = () => (isOpen.value = !isOpen.value)
const close = () => (isOpen.value = false)
const toggleDrawer = (key) => {
activeDrawer.value = activeDrawer.value === key ? null : key
}
// ✅ ferme automatiquement le mobile drawer si on navigue
const route = useRoute()
watch(() => route.fullPath, () => {
close()
activeDrawer.value = null
})
</script>
<style lang="scss">
.icon_mobile_agenda {
width: 35px;
margin-top: 10px;
img {
width: 100%
}
}
.icon_mobile_ticket {
width: 61px;
img {
width: 100%
}
}
</style>

View File

@@ -0,0 +1,21 @@
<script setup>
defineProps({
theme: { type: String, default: 'dark' }
})
</script>
<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" />
</div>
<div class="header_layout" :class="`header--${theme}`">
<slot />
</div>
</header>
</template>

View File

@@ -1,77 +0,0 @@
<script setup>
defineProps({
logoSrc: {
type: String,
required: true
},
logoAlt: {
type: String,
required: true
},
imgAgendaSrc: {
type: String,
required: true
}
})
</script>
<template>
<div class="header_navigation">
<div class="height_10"></div>
<nav class="header_navigation_topbar">
<div class="header_nav_item">Professionnels</div>
<div class="header_nav_item header_nav_lang">
<div class="header_nav_lang_item">FR</div>
<div class="header_nav_lang_item">/</div>
<div class="header_nav_lang_item">EN</div>
</div>
</nav>
<div class="height_20"></div>
<div class="header_navigation_main">
<div class="header_nav_logo">
<NuxtImg
:src="logoSrc"
:alt="logoAlt"
class="logo-img"
/>
</div>
<nav class="header_nav_cont">
<div class="header_nav">
<div class="header_nav_item brandontext_bold">
<NuxtLink to="/">L'Orchestre</NuxtLink>
</div>
<div class="header_nav_item">
<NuxtLink to="/agenda">Concerts</NuxtLink>
</div>
<div class="header_nav_item brandontext_bold">
<NuxtLink to="/agenda">Éducation et médiation</NuxtLink>
</div>
<div class="header_nav_item">
<NuxtLink to="/agenda">Mécénat</NuxtLink>
</div>
<div class="header_nav_item">
<NuxtLink to="/agenda">
<div class="nav_icone">
<div class="nav_icone_img"><img :src="imgAgendaSrc" alt="icone agenda"></div>
<div>Agenda</div>
</div>
</NuxtLink>
</div>
</div>
</nav>
</div>
<div class="height_25"></div>
</div>
</template>
<style>
</style>

View File

@@ -1,36 +0,0 @@
<script setup>
import agenda from '@/assets/img/icones/agenda_rouge_fonce_blanc.svg'
</script>
<template>
<div class="header_full">
<header_content
logo-src="/img/logos/logo_blanc_rouge.png"
logo-alt="Logo de l'orchestre National d'Île-de-france en concert"
:img-agenda-src="agenda"
/>
<div class="obscur"></div>
<div class="header-img_cont">
<NuxtImg
src="/img/photos/zaho.jpg"
placeholder
preset="full"
alt="L'orchestre National d'Île-de-france en concert - vue d'ensemble"
class="header-img"
/>
</div>
<div class="header-img_text">
<div class="header-img_titre">ZAHO DE SAGAZAN</div>
<div class="header-img_description">Accompagnée par lOrchestre national dÎle-de-France dirigé par Dylan Corlay, Zaho de Sagazan revisite les chansons de son premier album pour les plonger dans une toute nouvelle dimension !</div>
<div class="decouvrir"><div class="decouvrir_icone"><img src="@/assets/img/icones/fleche_gris_blanc.svg" alt="icone flèche"></div><div class="decouvrir_texte">Découvrir</div></div>
</div>
</div>
</template>

View File

@@ -0,0 +1,59 @@
<!--
La section par défaut fait la largeur de la page.
On peut mettre de la couleur ou pas.
C'est le contenu de la section (PageSectionInner) qui aura une marge.
Et avec "content" à "false" on peut dire aussi qu'on n'utilise pas le PageSectionInner, au cas où...
-->
<template>
<section
class="page-section"
:class="[
`page-section--${tone}`,
{ 'page-section--padded': padded }
]"
>
<!-- Si content == true -->
<PageSectionInner v-if="content" :size="contentSize" :padt="padt" :padb="padb">
<slot />
</PageSectionInner>
<!-- Si content == false -->
<template v-else>
<slot />
</template>
</section>
</template>
<script setup>
defineProps({
tone: { type: String, default: 'default' }, // default / brand / muted / dark…
padded: { type: Boolean, default: true }, // padding vertical
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
})
</script>
<style lang="scss">
.page-section {
position: relative;
width: 100%;
//min-height: var(--sp-200);
/* tons = arrière-plan section */
&--default { background: transparent; }
&--brand { background: var(--c-brand_rouge);}
&--dark { background: var(--c-backgroud-black); }
&--brandreverse { background: var(--c-backgroud-brandreverse); }
// padding en haut et en bas
&--padded {
padding-top: 30px;
padding-bottom: 50px;
}
}
</style>

View File

@@ -0,0 +1,99 @@
<!-- Pour gérer tous les types de main dans les différents templates de page
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}`]">
<slot />
</div>
</template>
<script setup>
defineProps({
size: { type: String, default: 'default' }, // default / wide / narrow
padb : { type: String, default: '' },
padt : { type: String, default: '' }
})
</script>
<style lang="scss">
.page-section--inner {
// ne dépasse jamais lécran
width: 100%;
// centre le bloc horizontalement, crée des marges externes fluides, fonctionne dans toutes les largeurs décran
margin-inline: auto;
// respiration sur les côtés avec marges minimale ( surtout utile pour mobiles)
// limite de largeur quand on veut une largeur plus petit (pour les articles par exemple)
&--narrow {
max-width: var(--container-narrow);
}
// limite de largeur (par défaut)
&--default {
/* mobile / small screens */
@media (max-width: 700px) {
padding-inline: var(--page-padding-mobile);
}
@media (min-width: 0px) {
max-width: 100%;
}
@media (min-width: 600px) {
max-width: 580px;
}
@media (min-width: 700px) {
max-width: 660px;
}
@media (min-width: 800px) {
max-width: 780px;
}
@media (min-width: 900px) {
max-width: 860px;
}
@media (min-width: 1000px) {
max-width: 950px;
}
@media (min-width: 1100px) {
max-width: 1020px;
}
@media (min-width: 1200px) {
max-width: 1100px;
}
@media (min-width: 1300px) {
max-width: 1200px;
}
@media (min-width: 1400px) {
max-width: 1300px;
}
@media (min-width: 1500px) {
max-width: 1400px;
}
}
// limite de largeur un peu plus grande que par défaut
&--wide {
max-width: var(--container-wide);
}
// Padding
&--padt--xs {
padding-top: 30px;
}
&--padt--sm {
padding-top: 45px;
}
&--padb--xs {
padding-bottom: 17px;
}
&--padb--sm {
padding-bottom: 30px;
}
}
</style>

View File

@@ -0,0 +1,60 @@
<template>
<div
:class="[
`section-content`,
`section-content--tone-${tone}`,
`section-content--pad-${pad}`
]"
>
<slot />
</div>
</template>
<script setup>
defineProps({
as: { type: String, default: 'h2' },
tone: { type: String, default: 'default' },
pad: { type: String, default: '' }, // xs, sm, md, lg
})
</script>
<style lang="scss">
.section-content {
&--tone-default { background: transparent; }
&--tone-brand { background: var(--c-brand_rouge); }
&--tone-brand_rouge45 { background: var(--c-brand_rouge45); }
&--tone-muted { background: var(--c-brand_rouge-weak); }
&--tone-dark { background: var(--c-backgroud-black); }
&--tone-brandreverse { background: var(--c-backgroud-brandreverse); }
&--pad-xs {
padding-top: var(--sp-32);
padding-bottom: var(--sp-16);
padding-left: var(--sp-45);
}
&--pad-sm {
padding-top: var(--sp-32);
padding-bottom: var(--sp-16);
padding-left: var(--sp-45);
}
&--pad-md {
padding-top: var(--sp-80);
padding-bottom: var(--sp-180);
padding-left: var(--sp-45);
}
&--pad-lg {
padding-top: var(--sp-80);
padding-bottom: var(--sp-180);
padding-left: var(--sp-45);
}
}
@media (max-width: 300px) {
.section-title {
padding-left: calc(var(--section-title-pl, var(--sp-45)) - 20px);
}
}
</style>

View File

@@ -0,0 +1,56 @@
<template>
<DsHeading
as="h1"
:tone="tone"
:class="[
`section-title`,
`section-title--pad-${pad}`
]"
>
<slot />
</DsHeading>
</template>
<script setup>
import DsHeading from '@root/design-system/primitives/DsHeading.vue'
defineProps({
as: { type: String, default: 'h2' },
tone: { type: String, default: 'default' },
pad: { type: String, default: 'sm' }, // xs, sm, md, lg
})
</script>
<style lang="scss">
.section-title {
&--pad-xs {
padding-top: var(--sp-32);
padding-bottom: var(--sp-16);
padding-left: var(--sp-45);
}
&--pad-sm {
padding-top: var(--sp-48);
padding-bottom: var(--sp-48);
padding-left: var(--sp-45);
}
&--pad-md {
padding-top: var(--sp-80);
padding-bottom: var(--sp-180);
padding-left: var(--sp-45);
}
&--pad-lg {
padding-top: var(--sp-80);
padding-bottom: var(--sp-180);
padding-left: var(--sp-45);
}
}
@media (max-width: 300px) {
.section-title {
padding-left: calc(var(--section-title-pl, var(--sp-45)) - 20px);
}
}
</style>