diff --git a/assets/css/src/pages/_agenda.scss b/assets/css/src/pages/_agenda.scss index 9784902..dfaf671 100644 --- a/assets/css/src/pages/_agenda.scss +++ b/assets/css/src/pages/_agenda.scss @@ -1,10 +1,13 @@ [data-template="agenda"] { main { background-color: transparent; + margin-top: -2px; .dates-container { - - + border: var(--border); + padding-bottom: 2rem; + border-radius: var(--radius); + background-color: var(--color-beige); [data-view="events"] { ul { @@ -15,6 +18,8 @@ } .month-switcher { + position: sticky; + top: 6.8rem; box-sizing: border-box; width: 100%; @@ -28,7 +33,6 @@ border-radius: var(--radius); background-color: var(--color-beige); - .month-label { margin: 2rem; } @@ -51,7 +55,6 @@ border-radius: var(--radius); background-color: var(--color-beige); - &:not(:last-child) { } @@ -66,31 +69,28 @@ max-width: 100%; } - .dates{ - + .dates { display: grid; grid-template-columns: repeat(2, 1fr); .date { margin: 2rem; - margin-bottom: 4rem ; + margin-bottom: 4rem; font-size: var(--font-size-L); - .date-range{ + .date-range { font-size: var(--font-size-XL); line-height: var(--line-height-XL); margin-bottom: var(--line-height-M); } - .date-place{ + .date-place { text-wrap: balance; } a { text-decoration: underline; } } - } - } } } diff --git a/assets/images/characters/characters-kawai.svg b/assets/images/characters/characters-kawai.svg index 27262c7..0288881 100644 --- a/assets/images/characters/characters-kawai.svg +++ b/assets/images/characters/characters-kawai.svg @@ -76,5 +76,17 @@ + + + + + + + + + + + + diff --git a/assets/js/characters/morphEyes.js b/assets/js/characters/morphEyes.js new file mode 100644 index 0000000..a06ffad --- /dev/null +++ b/assets/js/characters/morphEyes.js @@ -0,0 +1,63 @@ +export function initMorphEyes() { + const svg = document.querySelector(".identity svg"); + if (!svg) return; + + gsap.registerPlugin(MorphSVGPlugin); + + const DURATION = 0.5; + const EASE = "power2.inOut"; + + // lc-eye-l : composé de plusieurs éléments superposés + const lcEyeLIris = svg.querySelector("#lc-eye-l-iris"); + const lcEyeLBase = svg.querySelector("#lc-eye-l-base"); + const lcEyeLOverlays = svg.querySelectorAll("#lc-eye-l-sclera, #lc-eye-l-shadow, #lc-eye-l-sparkle"); + + // Les trois autres yeux : un seul compound path chacun + const lcEyeRIris = svg.querySelector("#lc-eye-r-iris"); + const rcEyeLIris = svg.querySelector("#rc-eye-l-iris"); + const rcEyeRIris = svg.querySelector("#rc-eye-r-iris"); + + // Paupières + sourcils : révélés en fondu lors du passage en no-outfit + const eyeOverlays = svg.querySelector("#eye-overlays"); + + if (!lcEyeLIris || !lcEyeRIris || !rcEyeLIris || !rcEyeRIris) return; + + const origins = { + lcEyeLIris: lcEyeLIris.getAttribute("d"), + lcEyeLBase: lcEyeLBase.getAttribute("d"), + lcEyeRIris: lcEyeRIris.getAttribute("d"), + rcEyeLIris: rcEyeLIris.getAttribute("d"), + rcEyeRIris: rcEyeRIris.getAttribute("d"), + }; + + function morphToNoOutfit() { + // lc-eye-l : iris + base → ovale, overlays blancs → opacity 0 + gsap.to(lcEyeLIris, { morphSVG: "#lc-eye-l-target", duration: DURATION, ease: EASE }); + gsap.to(lcEyeLBase, { morphSVG: "#lc-eye-l-target", duration: DURATION, ease: EASE }); + gsap.to(lcEyeLOverlays, { opacity: 0, duration: DURATION * 0.4, ease: "power1.in" }); + + gsap.to(lcEyeRIris, { morphSVG: "#lc-eye-r-target", duration: DURATION, delay: 0.04, ease: EASE }); + gsap.to(rcEyeLIris, { morphSVG: "#rc-eye-l-target", duration: DURATION, delay: 0.02, ease: EASE }); + gsap.to(rcEyeRIris, { morphSVG: "#rc-eye-r-target", duration: DURATION, delay: 0.06, ease: EASE }); + + // Paupières + sourcils : apparition en fondu + gsap.to(eyeOverlays, { opacity: 1, duration: DURATION * 0.8, delay: DURATION * 0.3, ease: "power1.out" }); + } + + function morphToKawai() { + gsap.to(lcEyeLIris, { morphSVG: origins.lcEyeLIris, duration: DURATION, ease: EASE }); + gsap.to(lcEyeLBase, { morphSVG: origins.lcEyeLBase, duration: DURATION, ease: EASE }); + gsap.to(lcEyeLOverlays, { opacity: 1, duration: DURATION * 0.6, delay: DURATION * 0.5, ease: "power1.out" }); + + gsap.to(lcEyeRIris, { morphSVG: origins.lcEyeRIris, duration: DURATION, delay: 0.04, ease: EASE }); + gsap.to(rcEyeLIris, { morphSVG: origins.rcEyeLIris, duration: DURATION, delay: 0.02, ease: EASE }); + gsap.to(rcEyeRIris, { morphSVG: origins.rcEyeRIris, duration: DURATION, delay: 0.06, ease: EASE }); + + // Paupières + sourcils : disparition immédiate + gsap.to(eyeOverlays, { opacity: 0, duration: DURATION * 0.4, ease: "power1.in" }); + } + + const identity = document.querySelector(".identity"); + identity.addEventListener("mouseenter", morphToNoOutfit); + identity.addEventListener("mouseleave", morphToKawai); +} diff --git a/assets/js/characters/morphMouth.js b/assets/js/characters/morphMouth.js new file mode 100644 index 0000000..0096da3 --- /dev/null +++ b/assets/js/characters/morphMouth.js @@ -0,0 +1,57 @@ +export function initMorphMouth() { + const svg = document.querySelector(".identity svg"); + if (!svg) return; + + const lcMouth = svg.querySelector("#lc-mouth"); + const rcMouth = svg.querySelector("#rc-mouth"); + if (!lcMouth || !rcMouth) return; + + gsap.registerPlugin(MorphSVGPlugin); + + const lcMouthOrigin = lcMouth.getAttribute("d"); + const rcMouthOrigin = rcMouth.getAttribute("d"); + + const DURATION = 0.3; + const EASE = "power2.inOut"; + const STAGGER = 0.06; + + function morphToNoOutfit() { + gsap.to(lcMouth, { + morphSVG: "#lc-mouth-target", + fill: "black", + stroke: "transparent", + duration: DURATION, + ease: EASE, + }); + gsap.to(rcMouth, { + morphSVG: "#rc-mouth-target", + fill: "black", + stroke: "transparent", + duration: DURATION, + delay: STAGGER, + ease: EASE, + }); + } + + function morphToKawai() { + gsap.to(lcMouth, { + morphSVG: lcMouthOrigin, + fill: "none", + stroke: "black", + duration: DURATION, + ease: EASE, + }); + gsap.to(rcMouth, { + morphSVG: rcMouthOrigin, + fill: "none", + stroke: "black", + duration: DURATION, + delay: STAGGER, + ease: EASE, + }); + } + + const identity = document.querySelector(".identity"); + identity.addEventListener("mouseenter", morphToNoOutfit); + identity.addEventListener("mouseleave", morphToKawai); +}