commit 2405eb32c1d5fb5b1c365bbaed3c4ef44302e07e Author: Valentin Le Moign Date: Mon May 18 23:07:31 2026 +0200 first commit diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..aef8443 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "liveServer.settings.port": 5501 +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/app.js b/app.js new file mode 100644 index 0000000..f615140 --- /dev/null +++ b/app.js @@ -0,0 +1,242 @@ +/* ---------------------------------------------------------------- + Le Shed — Initialisation + 1. Injection des motifs décoratifs (formes vectorielles colorées) + 2. Initialisation de Rellax sur les objets décoratifs + 3. Parallax custom de la colonne droite : + - Les deux colonnes démarrent à la même hauteur (top aligné) + - Les deux colonnes finissent à la même hauteur (bottom aligné) + - Le translateY est appliqué sur .col__cards (wrapper interne) + pour ne pas casser le position:sticky du heading. + ---------------------------------------------------------------- */ + +document.addEventListener('DOMContentLoaded', function () { + + /* ---- Header compact au scroll + padding-top dynamique ---- */ + + var masthead = document.querySelector('.masthead'); + var layout = document.querySelector('.layout'); + + var headerSyncing = false; + + function syncHeaderHeight() { + if (!masthead || !layout) return; + var h = masthead.offsetHeight; + layout.style.paddingTop = h + 'px'; + document.documentElement.style.setProperty('--header-h', h + 'px'); + } + + function syncHeaderLoop() { + syncHeaderHeight(); + syncColHeadingH(); + if (headerSyncing) requestAnimationFrame(syncHeaderLoop); + } + + function startHeaderSync() { + if (headerSyncing) return; + headerSyncing = true; + syncHeaderLoop(); + setTimeout(function () { + headerSyncing = false; + syncHeaderHeight(); + }, 350); + } + + function syncColHeadingH() { + var headingLeft = document.querySelector('.col--left .col__heading'); + if (headingLeft) { + document.documentElement.style.setProperty('--col-heading-h', headingLeft.offsetHeight + 'px'); + } + } + + function onHeaderScroll() { + if (!masthead) return; + var scrolled = window.scrollY > 20; + if (scrolled !== masthead.classList.contains('is-compact')) { + masthead.classList.toggle('is-compact', scrolled); + startHeaderSync(); + } + } + + syncHeaderHeight(); + syncColHeadingH(); + window.addEventListener('resize', function () { syncHeaderHeight(); syncColHeadingH(); }); + window.addEventListener('scroll', onHeaderScroll, { passive: true }); + onHeaderScroll(); + + /* ---- Rellax pour les objets décoratifs uniquement ---- */ + + function initRellax() { + var rellax = new Rellax('[data-rellax-speed]', { + center: false, + wrapper: null, + round: true, + vertical: true, + horizontal: false + }); + + window.addEventListener('resize', function () { + rellax.refresh(); + }); + } + + /* ---- Parallax custom colonne droite ---- */ + + function initColumnParallax() { + var colLeft = document.querySelector('.col--left'); + var colRight = document.querySelector('.col--right'); + var cardsRight = document.querySelector('.col--right .col__cards'); + if (!colLeft || !colRight || !cardsRight) return; + + var titlesRight = Array.from(colRight.querySelectorAll('.col__cards .card__title')); + var ticking = false; + var dims = {}; + var maxScroll = 0; + var currentOffset = 0; + + // top de base des titres sticky (sans parallax) + var baseStickyTop = 0; + + function readBaseStickyTop() { + var headerH = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--header-h')) || 80; + var headingRight = colRight.querySelector('.col__heading'); + var colHeadingH = headingRight ? headingRight.offsetHeight : 35; + baseStickyTop = headerH + colHeadingH - 2; + } + + function recalc() { + cardsRight.style.transform = ''; + titlesRight.forEach(function (t) { t.style.top = ''; }); + layout.style.height = ''; + dims.leftH = colLeft.offsetHeight; + dims.rightH = colRight.offsetHeight; + + var cs = getComputedStyle(layout); + var padTop = parseFloat(cs.paddingTop) || 0; + var padBot = parseFloat(cs.paddingBottom) || 0; + var minColH = Math.min(dims.leftH, dims.rightH); + layout.style.height = (padTop + minColH + padBot) + 'px'; + + maxScroll = Math.max(1, document.documentElement.scrollHeight - window.innerHeight); + readBaseStickyTop(); + } + + function onScroll() { + if (!ticking) { + ticking = true; + requestAnimationFrame(function () { + readBaseStickyTop(); + var progress = Math.min(1, Math.max(0, window.scrollY / maxScroll)); + var delta = dims.leftH - dims.rightH; + currentOffset = Math.round(delta * progress); + cardsRight.style.transform = 'translateY(' + currentOffset + 'px)'; + // Compenser le translateY sur le top des titres sticky + // pour qu'ils se collent toujours juste sous "Actions publiques" + var correctedTop = baseStickyTop - currentOffset; + titlesRight.forEach(function (t) { + t.style.top = correctedTop + 'px'; + }); + ticking = false; + }); + } + } + + recalc(); + window.addEventListener('scroll', onScroll, { passive: true }); + window.addEventListener('resize', function () { + recalc(); + onScroll(); + }); + + onScroll(); + } + + /* ---- Settings panel toggle ---- */ + + var settingsBtn = document.getElementById('settings-toggle'); + var settingsPanel = document.getElementById('settings-panel'); + + if (settingsBtn && settingsPanel) { + settingsBtn.addEventListener('click', function () { + settingsPanel.hidden = !settingsPanel.hidden; + }); + + document.addEventListener('click', function (e) { + if (!document.getElementById('settings').contains(e.target)) { + settingsPanel.hidden = true; + } + }); + } + + /* ---- Switch motifs ---- */ + + var rellaxInstance = null; + + function clearMotifs() { + document.querySelectorAll('.objets-layer, .objets2-layer, .paysage-layer').forEach(function (el) { + el.remove(); + }); + if (rellaxInstance) { + try { rellaxInstance.destroy(); } catch (e) {} + rellaxInstance = null; + } + } + + function activateMotif(mode) { + clearMotifs(); + if (mode === 'paysage' && window.LeShedPaysage) { + window.LeShedPaysage.inject().then(function () { + rellaxInstance = new Rellax('[data-rellax-speed]', { center: false, round: true, vertical: true, horizontal: false }); + }); + } else if (mode === 'objets' && window.LeShedObjets) { + window.LeShedObjets.inject().then(function () { + rellaxInstance = new Rellax('[data-rellax-speed]', { center: false, round: true, vertical: true, horizontal: false }); + }); + } else if (mode === 'objets2' && window.LeShedObjets2) { + window.LeShedObjets2.inject().then(function () { + rellaxInstance = new Rellax('[data-rellax-speed]', { center: false, round: true, vertical: true, horizontal: false }); + }); + } + } + + document.querySelectorAll('input[name="motifs"]').forEach(function (radio) { + radio.addEventListener('change', function () { + if (radio.checked) activateMotif(radio.value); + }); + }); + + /* ---- Couleur motifs ---- */ + + var couleurCustomInput = document.getElementById('couleur-custom'); + + function applyMotifColor(value) { + var color = value === 'custom' ? couleurCustomInput.value : value; + document.documentElement.style.setProperty('--motif-color', color); + } + + document.querySelectorAll('input[name="couleur"]').forEach(function (radio) { + radio.addEventListener('change', function () { + if (radio.checked) applyMotifColor(radio.value); + }); + }); + + if (couleurCustomInput) { + couleurCustomInput.addEventListener('input', function () { + var customRadio = document.querySelector('input[name="couleur"][value="custom"]'); + if (customRadio) customRadio.checked = true; + applyMotifColor('custom'); + }); + } + + /* ---- Boot ---- */ + + document.querySelectorAll('input[name="motifs"]').forEach(function (r) { + r.checked = r.value === 'objets2'; + }); + document.querySelectorAll('input[name="couleur"]').forEach(function (r) { + r.checked = r.value === '#1a1a1a'; + }); + applyMotifColor('#1a1a1a'); + activateMotif('objets2'); + initColumnParallax(); + +}); diff --git a/assets/Screenshot_bas_de_page.png b/assets/Screenshot_bas_de_page.png new file mode 100644 index 0000000..2e95423 Binary files /dev/null and b/assets/Screenshot_bas_de_page.png differ diff --git a/assets/fonts/BVHAntoPlotTrial-LightItalic.otf b/assets/fonts/BVHAntoPlotTrial-LightItalic.otf new file mode 100644 index 0000000..fcde1a9 Binary files /dev/null and b/assets/fonts/BVHAntoPlotTrial-LightItalic.otf differ diff --git a/assets/images/appel-a-cueillir.png b/assets/images/appel-a-cueillir.png new file mode 100644 index 0000000..87c57ee Binary files /dev/null and b/assets/images/appel-a-cueillir.png differ diff --git a/assets/images/arena.png b/assets/images/arena.png new file mode 100644 index 0000000..c76ba5c Binary files /dev/null and b/assets/images/arena.png differ diff --git a/assets/images/bonus.png b/assets/images/bonus.png new file mode 100644 index 0000000..1152a70 Binary files /dev/null and b/assets/images/bonus.png differ diff --git a/assets/images/danser.png b/assets/images/danser.png new file mode 100644 index 0000000..f8d4ffa Binary files /dev/null and b/assets/images/danser.png differ diff --git a/assets/images/hermine-bouvier.png b/assets/images/hermine-bouvier.png new file mode 100644 index 0000000..fdbedc9 Binary files /dev/null and b/assets/images/hermine-bouvier.png differ diff --git a/assets/images/rice-power.png b/assets/images/rice-power.png new file mode 100644 index 0000000..25c4673 Binary files /dev/null and b/assets/images/rice-power.png differ diff --git a/assets/images/the-underways.png b/assets/images/the-underways.png new file mode 100644 index 0000000..ba32ba2 Binary files /dev/null and b/assets/images/the-underways.png differ diff --git a/assets/images/vide-matrices.png b/assets/images/vide-matrices.png new file mode 100644 index 0000000..bb462a2 Binary files /dev/null and b/assets/images/vide-matrices.png differ diff --git a/assets/objets/objet-01.svg b/assets/objets/objet-01.svg new file mode 100644 index 0000000..f291102 --- /dev/null +++ b/assets/objets/objet-01.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/objets/objet-02.svg b/assets/objets/objet-02.svg new file mode 100644 index 0000000..3a0f9fe --- /dev/null +++ b/assets/objets/objet-02.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/objets/objet-03.svg b/assets/objets/objet-03.svg new file mode 100644 index 0000000..658ef55 --- /dev/null +++ b/assets/objets/objet-03.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/objets/objet-04.svg b/assets/objets/objet-04.svg new file mode 100644 index 0000000..c07ea2b --- /dev/null +++ b/assets/objets/objet-04.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/objets/objet-05.svg b/assets/objets/objet-05.svg new file mode 100644 index 0000000..15675b8 --- /dev/null +++ b/assets/objets/objet-05.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/objets/objet-06.svg b/assets/objets/objet-06.svg new file mode 100644 index 0000000..d35facd --- /dev/null +++ b/assets/objets/objet-06.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/objets/objet-07.svg b/assets/objets/objet-07.svg new file mode 100644 index 0000000..1302fe6 --- /dev/null +++ b/assets/objets/objet-07.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/objets/objet-08.svg b/assets/objets/objet-08.svg new file mode 100644 index 0000000..ba95716 --- /dev/null +++ b/assets/objets/objet-08.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/objets/objet-09.svg b/assets/objets/objet-09.svg new file mode 100644 index 0000000..0b1b929 --- /dev/null +++ b/assets/objets/objet-09.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/assets/objets/objet-10.svg b/assets/objets/objet-10.svg new file mode 100644 index 0000000..b7a6069 --- /dev/null +++ b/assets/objets/objet-10.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/objets/objet-11.svg b/assets/objets/objet-11.svg new file mode 100644 index 0000000..66ed5f9 --- /dev/null +++ b/assets/objets/objet-11.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/objets/objet-12.svg b/assets/objets/objet-12.svg new file mode 100644 index 0000000..0c08a43 --- /dev/null +++ b/assets/objets/objet-12.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/assets/objets/objet-13.svg b/assets/objets/objet-13.svg new file mode 100644 index 0000000..9a66225 --- /dev/null +++ b/assets/objets/objet-13.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/objets/objet-14.svg b/assets/objets/objet-14.svg new file mode 100644 index 0000000..59d7d7e --- /dev/null +++ b/assets/objets/objet-14.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/objets/objet-15.svg b/assets/objets/objet-15.svg new file mode 100644 index 0000000..b903eaf --- /dev/null +++ b/assets/objets/objet-15.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/shapes/Path-10.svg b/assets/shapes/Path-10.svg new file mode 100644 index 0000000..1d95f7d --- /dev/null +++ b/assets/shapes/Path-10.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Path-2.svg b/assets/shapes/Path-2.svg new file mode 100644 index 0000000..6177c53 --- /dev/null +++ b/assets/shapes/Path-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Path-3.svg b/assets/shapes/Path-3.svg new file mode 100644 index 0000000..d347736 --- /dev/null +++ b/assets/shapes/Path-3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Path-4.svg b/assets/shapes/Path-4.svg new file mode 100644 index 0000000..0ac30b7 --- /dev/null +++ b/assets/shapes/Path-4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Path-5.svg b/assets/shapes/Path-5.svg new file mode 100644 index 0000000..ff49e12 --- /dev/null +++ b/assets/shapes/Path-5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Path-6.svg b/assets/shapes/Path-6.svg new file mode 100644 index 0000000..bbebf5e --- /dev/null +++ b/assets/shapes/Path-6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Path-7.svg b/assets/shapes/Path-7.svg new file mode 100644 index 0000000..a32f3e5 --- /dev/null +++ b/assets/shapes/Path-7.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Path-8.svg b/assets/shapes/Path-8.svg new file mode 100644 index 0000000..ea1ef06 --- /dev/null +++ b/assets/shapes/Path-8.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Path-9.svg b/assets/shapes/Path-9.svg new file mode 100644 index 0000000..41486ec --- /dev/null +++ b/assets/shapes/Path-9.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Path.svg b/assets/shapes/Path.svg new file mode 100644 index 0000000..14f1f9a --- /dev/null +++ b/assets/shapes/Path.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Rectangle-2.svg b/assets/shapes/Rectangle-2.svg new file mode 100644 index 0000000..f21b983 --- /dev/null +++ b/assets/shapes/Rectangle-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Rectangle-3.svg b/assets/shapes/Rectangle-3.svg new file mode 100644 index 0000000..ece721f --- /dev/null +++ b/assets/shapes/Rectangle-3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Rectangle-4.svg b/assets/shapes/Rectangle-4.svg new file mode 100644 index 0000000..8039272 --- /dev/null +++ b/assets/shapes/Rectangle-4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Rectangle-5.svg b/assets/shapes/Rectangle-5.svg new file mode 100644 index 0000000..33c0601 --- /dev/null +++ b/assets/shapes/Rectangle-5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Rectangle-6.svg b/assets/shapes/Rectangle-6.svg new file mode 100644 index 0000000..eb95ee6 --- /dev/null +++ b/assets/shapes/Rectangle-6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Rectangle-7.svg b/assets/shapes/Rectangle-7.svg new file mode 100644 index 0000000..1f85451 --- /dev/null +++ b/assets/shapes/Rectangle-7.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Rectangle-8.svg b/assets/shapes/Rectangle-8.svg new file mode 100644 index 0000000..274908e --- /dev/null +++ b/assets/shapes/Rectangle-8.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Rectangle-9.svg b/assets/shapes/Rectangle-9.svg new file mode 100644 index 0000000..8ca3491 --- /dev/null +++ b/assets/shapes/Rectangle-9.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Rectangle.svg b/assets/shapes/Rectangle.svg new file mode 100644 index 0000000..49774f7 --- /dev/null +++ b/assets/shapes/Rectangle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Union-2.svg b/assets/shapes/Union-2.svg new file mode 100644 index 0000000..0b6edfa --- /dev/null +++ b/assets/shapes/Union-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/Union.svg b/assets/shapes/Union.svg new file mode 100644 index 0000000..b665c63 --- /dev/null +++ b/assets/shapes/Union.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/horizontaux/Group-10.svg b/assets/shapes/v5-bach/horizontaux/Group-10.svg new file mode 100644 index 0000000..ca61791 --- /dev/null +++ b/assets/shapes/v5-bach/horizontaux/Group-10.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/horizontaux/Group-2.svg b/assets/shapes/v5-bach/horizontaux/Group-2.svg new file mode 100644 index 0000000..5c01940 --- /dev/null +++ b/assets/shapes/v5-bach/horizontaux/Group-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/horizontaux/Group-3.svg b/assets/shapes/v5-bach/horizontaux/Group-3.svg new file mode 100644 index 0000000..2a98772 --- /dev/null +++ b/assets/shapes/v5-bach/horizontaux/Group-3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/horizontaux/Group-4.svg b/assets/shapes/v5-bach/horizontaux/Group-4.svg new file mode 100644 index 0000000..6b975ff --- /dev/null +++ b/assets/shapes/v5-bach/horizontaux/Group-4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/horizontaux/Group-5.svg b/assets/shapes/v5-bach/horizontaux/Group-5.svg new file mode 100644 index 0000000..41976f7 --- /dev/null +++ b/assets/shapes/v5-bach/horizontaux/Group-5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/horizontaux/Group-6.svg b/assets/shapes/v5-bach/horizontaux/Group-6.svg new file mode 100644 index 0000000..1b74a53 --- /dev/null +++ b/assets/shapes/v5-bach/horizontaux/Group-6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/horizontaux/Group-7.svg b/assets/shapes/v5-bach/horizontaux/Group-7.svg new file mode 100644 index 0000000..1339aa4 --- /dev/null +++ b/assets/shapes/v5-bach/horizontaux/Group-7.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/horizontaux/Group-8.svg b/assets/shapes/v5-bach/horizontaux/Group-8.svg new file mode 100644 index 0000000..faaf155 --- /dev/null +++ b/assets/shapes/v5-bach/horizontaux/Group-8.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/horizontaux/Group-9.svg b/assets/shapes/v5-bach/horizontaux/Group-9.svg new file mode 100644 index 0000000..5ee2412 --- /dev/null +++ b/assets/shapes/v5-bach/horizontaux/Group-9.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/horizontaux/Group.svg b/assets/shapes/v5-bach/horizontaux/Group.svg new file mode 100644 index 0000000..8ab377e --- /dev/null +++ b/assets/shapes/v5-bach/horizontaux/Group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/verticaux/Group-10.svg b/assets/shapes/v5-bach/verticaux/Group-10.svg new file mode 100644 index 0000000..8d21e48 --- /dev/null +++ b/assets/shapes/v5-bach/verticaux/Group-10.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/verticaux/Group-11.svg b/assets/shapes/v5-bach/verticaux/Group-11.svg new file mode 100644 index 0000000..49bb39d --- /dev/null +++ b/assets/shapes/v5-bach/verticaux/Group-11.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/verticaux/Group-12.svg b/assets/shapes/v5-bach/verticaux/Group-12.svg new file mode 100644 index 0000000..53e870a --- /dev/null +++ b/assets/shapes/v5-bach/verticaux/Group-12.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/verticaux/Group-2.svg b/assets/shapes/v5-bach/verticaux/Group-2.svg new file mode 100644 index 0000000..4fa45a4 --- /dev/null +++ b/assets/shapes/v5-bach/verticaux/Group-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/verticaux/Group-3.svg b/assets/shapes/v5-bach/verticaux/Group-3.svg new file mode 100644 index 0000000..2320ff2 --- /dev/null +++ b/assets/shapes/v5-bach/verticaux/Group-3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/verticaux/Group-4.svg b/assets/shapes/v5-bach/verticaux/Group-4.svg new file mode 100644 index 0000000..dadc710 --- /dev/null +++ b/assets/shapes/v5-bach/verticaux/Group-4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/verticaux/Group-5.svg b/assets/shapes/v5-bach/verticaux/Group-5.svg new file mode 100644 index 0000000..8340038 --- /dev/null +++ b/assets/shapes/v5-bach/verticaux/Group-5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/verticaux/Group-6.svg b/assets/shapes/v5-bach/verticaux/Group-6.svg new file mode 100644 index 0000000..d4a137a --- /dev/null +++ b/assets/shapes/v5-bach/verticaux/Group-6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/verticaux/Group-7.svg b/assets/shapes/v5-bach/verticaux/Group-7.svg new file mode 100644 index 0000000..080a244 --- /dev/null +++ b/assets/shapes/v5-bach/verticaux/Group-7.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/verticaux/Group-8.svg b/assets/shapes/v5-bach/verticaux/Group-8.svg new file mode 100644 index 0000000..5c832c8 --- /dev/null +++ b/assets/shapes/v5-bach/verticaux/Group-8.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/verticaux/Group-9.svg b/assets/shapes/v5-bach/verticaux/Group-9.svg new file mode 100644 index 0000000..d34c9a1 --- /dev/null +++ b/assets/shapes/v5-bach/verticaux/Group-9.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/shapes/v5-bach/verticaux/Group.svg b/assets/shapes/v5-bach/verticaux/Group.svg new file mode 100644 index 0000000..37f37de --- /dev/null +++ b/assets/shapes/v5-bach/verticaux/Group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/formes-elementaires-data.js b/formes-elementaires-data.js new file mode 100644 index 0000000..f81572a --- /dev/null +++ b/formes-elementaires-data.js @@ -0,0 +1,86 @@ +window.LeShedFormesElementaires = { + "Path-10": { + vbX: 1967, vbY: 689, vbW: 20.388, vbH: 29.152, + d: "M1986.6759033203125,697.6510620117188C1985.888916015625,694.7062377929688,1984.3258056640625,692.3023681640625,1982.6759033203125,691.1510620117188C1979.888916015625,689.2062377929688,1977.388916015625,688.7062377929688,1974.6759033203125,689.1510620117188C1971.735107421875,689.6332397460938,1968.388916015625,694.7062377929688,1967.6759033203125,698.1510620117188C1967.0364990234375,701.2405395507812,1966.681884765625,706.5848999023438,1967.388916015625,708.7062377929688C1967.888916015625,710.2062377929688,1968.4176025390625,711.9410400390625,1969.888916015625,713.7062377929688C1971.6019287109375,715.7614135742188,1974.888916015625,718.2062377929688,1978.6759033203125,718.1510620117188C1982.0245361328125,718.102294921875,1985.388916015625,713.2062377929688,1986.6759033203125,709.6510620117188C1987.6048583984375,707.0848388671875,1987.645751953125,701.2801513671875,1986.6759033203125,697.6510620117188" + }, + "Path-2": { + vbX: 1112, vbY: 783, vbW: 118, vbH: 79, + d: "M1226.5,829L1118.540283203125,791.671875C1117.6824951171875,791.4130859375,1115.693603515625,790.2081298828125,1114.5,788.5C1112.814208984375,786.087890625,1112,783,1112,783L1116,817L1224.869384765625,854.6026611328125C1224.869384765625,854.6026611328125,1226.52587890625,854.87451171875,1228,857C1229.9462890625,859.80615234375,1230,862,1230,862L1226.5,829" + }, + "Path-3": { + vbX: 1004, vbY: 599, vbW: 8, vbH: 67, + d: "M1012,633L1008.5,599C1008.5,599,1008.73046875,602.2128295898438,1008,608.5C1007.40576171875,613.6141357421875,1007,618,1007,618L1004,638L1007.5,666L1012,633" + }, + "Path-4": { + vbX: 1112, vbY: 704, vbW: 173.5, vbH: 91, + d: "M1282,762L1118.540283203125,712.671875C1117.6824951171875,712.4130859375,1115.693603515625,711.2081298828125,1114.5,709.5C1112.814208984375,707.087890625,1112,704,1112,704L1116,738L1280.369384765625,787.6026611328125C1280.369384765625,787.6026611328125,1282.02587890625,787.87451171875,1283.5,790C1285.4462890625,792.80615234375,1285.5,795,1285.5,795L1282,762" + }, + "Path-5": { + vbX: 720.037, vbY: 674, vbW: 76.463, vbH: 127.909, + d: "M724.5368041992188,709L720.0368041992188,674C720.0368041992188,674,720.5368041992188,677.5,721.5368041992188,679.5C724.79248046875,686.0115356445312,747,711.4547119140625,747,711.4547119140625L793,766.409423828125L796.5,801.909423828125C796.5,801.909423828125,795.8772583007812,798.6639404296875,792.5,791.909423828125C791.5,789.909423828125,785.6637573242188,783.60693359375,785.6637573242188,783.60693359375L724.5368041992188,709" + }, + "Path-6": { + vbX: 676.037, vbY: 556, vbW: 120.463, vbH: 177.455, + d: "M680.5368041992188,591L676.0368041992188,556C676.0368041992188,556,676.5368041992188,559.5,677.5368041992188,561.5C680.79248046875,568.0115356445312,703,593.4547119140625,703,593.4547119140625L793,697.9547119140625L796.5,733.4547119140625C796.5,733.4547119140625,795.8772583007812,730.209228515625,792.5,723.4547119140625C791.5,721.4547119140625,785.6637573242188,715.1522216796875,785.6637573242188,715.1522216796875L680.5368041992188,591" + }, + "Path-7": { + vbX: 649, vbY: 449, vbW: 147.5, vbH: 217, + d: "M653.5,484L649,449C649,449,649.5,452.5,650.5,454.5C653.7556762695312,461.01153564453125,675.9631958007812,486.4547119140625,675.9631958007812,486.4547119140625L793,630.5L796.5,666C796.5,666,795.8772583007812,662.7545166015625,792.5,656C791.5,654,785.6637573242188,647.697509765625,785.6637573242188,647.697509765625L653.5,484" + }, + "Path-8": { + vbX: 977, vbY: 440, vbW: 31, vbH: 159, + d: "M1008,474L1004.5,440C1004.5,440,1004.73046875,443.21282958984375,1004,449.5C1003.40576171875,454.6141357421875,1002.51318359375,457.10198974609375,1002.51318359375,457.10198974609375L977,571L980.5,599L1008,474" + }, + "Path-9": { + vbX: 993, vbY: 519, vbW: 18, vbH: 108, + d: "M1011,553L1007.5,519C1007.5,519,1007.73046875,522.2128295898438,1007,528.5C1006.40576171875,533.6141357421875,1005.51318359375,536.1019897460938,1005.51318359375,536.1019897460938L993,599L996.5,627L1011,553" + }, + "Path": { + vbX: 1112, vbY: 863, vbW: 57, vbH: 61, + d: "M1165.5,891L1118.540283203125,871.671875C1117.6824951171875,871.4130859375,1115.693603515625,870.2081298828125,1114.5,868.5C1112.814208984375,866.087890625,1112,863,1112,863L1116,897L1163.869384765625,916.6026611328125C1163.869384765625,916.6026611328125,1165.52587890625,916.87451171875,1167,919C1168.9462890625,921.80615234375,1169,924,1169,924L1165.5,891" + }, + "Rectangle-2": { + vbX: 862, vbY: 503, vbW: 61.76, vbH: 151.082, + d: "M910.5802612304688,620.00146484375L873.9281616210938,517.3983764648438C873.9281616210938,517.3983764648438,873.1663208007812,515.3073120117188,872.2008666992188,511C871.0147705078125,505.7083740234375,870.7008666992188,503,870.7008666992188,503L874.7003784179688,537.5816650390625C905.7003784179688,621.5816650390625,909.3837280273438,634.2357788085938,911.0591430664062,639.5816650390625C914.0563354492188,649.144775390625,915.0591430664062,654.0816650390625,915.0591430664062,654.0816650390625L910.5802612304688,620.00146484375" + }, + "Rectangle-3": { + vbX: 1112.706, vbY: 454.067, vbW: 141.503, vbH: 116.433, + d: "M1129.94775390625,539.8450317382812L1229.2340087890625,473.6080322265625C1231.537109375,472.1519775390625,1232.694580078125,470.9024658203125,1233.231689453125,468.0667724609375C1234.1575927734375,463.1790771484375,1233.231689453125,454.0667724609375,1233.231689453125,454.0667724609375L1238,496L1135.922607421875,566.148193359375C1135.922607421875,566.148193359375,1135.087646484375,566.715087890625,1134.6839599609375,567.5C1133.5953369140625,569.6162719726562,1133.6839599609375,570.5,1133.6839599609375,570.5L1129.94775390625,539.8450317382812" + }, + "Rectangle-4": { + vbX: 1115.664, vbY: 418.067, vbW: 68.587, vbH: 74.366, + d: "M1129.94775390625,461.77825927734375L1162.2340087890625,437.6080322265625C1164.537109375,436.1519775390625,1165.694580078125,434.9024658203125,1166.231689453125,432.0667724609375C1167.1575927734375,427.1790771484375,1166.231689453125,418.0667724609375,1166.231689453125,418.0667724609375L1171,460L1135.922607421875,488.0814208984375C1135.922607421875,488.0814208984375,1135.087646484375,488.6483154296875,1134.6839599609375,489.4332275390625C1133.5953369140625,491.54949951171875,1133.6839599609375,492.4332275390625,1133.6839599609375,492.4332275390625L1129.94775390625,461.77825927734375" + }, + "Rectangle-5": { + vbX: 851, vbY: 408, vbW: 81.947, vbH: 209.5, + d: "M920.8798828125,583.4197998046875L861.8151245117188,422.39837646484375C861.8151245117188,422.39837646484375,861.0532836914062,420.30731201171875,860.0878295898438,416C858.9017333984375,410.7083740234375,858.5878295898438,408,858.5878295898438,408L862.5873413085938,442.5816650390625C918.349853515625,595.1365356445312,919.683349609375,597.6541137695312,921.3587646484375,603C924.35595703125,612.5631103515625,925.3587646484375,617.5,925.3587646484375,617.5L920.8798828125,583.4197998046875" + }, + "Rectangle-6": { + vbX: 1436.268, vbY: 460, vbW: 87.464, vbH: 76, + d: "M1447.72900390625,508.09576416015625C1447.72900390625,508.09576416015625,1453,491.00006103515625,1467,485C1481,479,1479.1871337890625,492.00384521484375,1494.8304443359375,485.90966796875C1510,480,1509,460,1509,460L1513,494C1513,494,1510,502,1500,506C1486.346435546875,511.46136474609375,1485,497,1469.5,505C1456.3720703125,511.77557373046875,1451,536,1451,536L1447.72900390625,508.09576416015625" + }, + "Rectangle-7": { + vbX: 1111, vbY: 498, vbW: 205.868, vbH: 151.5, + d: "M1129.94775390625,618.8450317382812L1290.186279296875,517.541259765625C1292.4893798828125,516.085205078125,1293.6468505859375,514.835693359375,1294.1839599609375,512C1295.10986328125,507.1123046875,1294.1839599609375,498,1294.1839599609375,498L1298.9522705078125,539.9332275390625L1135.922607421875,645.148193359375C1135.922607421875,645.148193359375,1135.087646484375,645.715087890625,1134.6839599609375,646.5C1133.5953369140625,648.6162719726562,1133.6839599609375,649.5,1133.6839599609375,649.5L1129.94775390625,618.8450317382812" + }, + "Rectangle-8": { + vbX: 1428.187, vbY: 521.923, vbW: 122.068, vbH: 102.077, + d: "M1443.72900390625,590.0957641601562C1443.72900390625,590.0957641601562,1446.9239501953125,566.8074340820312,1467,559C1485,552,1492.9422607421875,566.3335571289062,1508.8304443359375,560.90966796875C1532,553,1531.4423828125,521.9226684570312,1531.4423828125,521.9226684570312L1535,563C1535,563,1533,576,1514,583C1500.2012939453125,588.0836791992188,1491,572,1469.5,582C1450.3887939453125,590.8887329101562,1447,624,1447,624L1443.72900390625,590.0957641601562" + }, + "Rectangle-9": { + vbX: 1400, vbY: 608, vbW: 178.118, vbH: 131.28, + d: "M1415.568603515625,702.953857421875C1415.568603515625,702.953857421875,1423.62353515625,675.6633911132812,1454,662.5C1484,649.5,1495.668701171875,673.7095947265625,1519.8304443359375,665.40966796875C1554.5,653.5,1558.4031982421875,607.9999389648438,1558.4031982421875,607.9999389648438L1561.9608154296875,649.0772705078125C1561.9608154296875,649.0772705078125,1554.8670654296875,678.6610107421875,1525,687.5C1502.1661376953125,694.2573852539062,1491.3585205078125,669.3230590820312,1456.5,685.5C1421.967529296875,701.5252075195312,1418.839599609375,736.8580932617188,1418.839599609375,736.8580932617188L1415.568603515625,702.953857421875" + }, + "Rectangle": { + vbX: 872, vbY: 587, vbW: 46.16, vbH: 109.245, + d: "M905.5689697265625,662.1648559570312L883.3391723632812,601.3983764648438C883.3391723632812,601.3983764648438,882.5773315429688,599.3073120117188,881.6118774414062,595C880.42578125,589.7083740234375,880.1118774414062,587,880.1118774414062,587L884.1113891601562,621.5816650390625C902.6113891601562,671.0816650390625,904.3724365234375,676.399169921875,906.0478515625,681.7450561523438C909.0450439453125,691.3081665039062,910.0478515625,696.2450561523438,910.0478515625,696.2450561523438L905.5689697265625,662.1648559570312" + }, + "Union-2": { + vbX: 1824, vbY: 627, vbW: 57.5, vbH: 156, + d: "M1824,706.0789184570312C1824,697.4544067382812,1824.4686279296875,693.0402221679688,1825.5,686.0789184570312C1827,675.9544067382812,1829.5,666.4544067382812,1834.5,657.0789184570312C1838.029296875,650.4612426757812,1844,643.5789184570312,1851.2255859375,640.2817993164062C1860.48974609375,636.0543212890625,1867.7498779296875,635.1515502929688,1871.5579833984375,635.0191650390625C1871.898681640625,635.00732421875,1872.716552734375,634.6512451171875,1873,633.5C1873.5850830078125,631.1243896484375,1873.5,627,1873.5,627L1874.5,635.0789184570312L1877.907958984375,663.0407104492188C1877.907958984375,663.0407104492188,1868.265625,661.4014282226562,1854.436767578125,668.1155395507812C1845.5,672.4544067382812,1839.5,677.4544067382812,1835.686767578125,683.3385620117188C1831.496337890625,689.8046264648438,1828.78369140625,699.9486694335938,1828.78369140625,706.9965209960938C1828.78369140625,715.4591674804688,1832.5,724.9544067382812,1835.686767578125,730.6546020507812C1839.3779296875,737.2568969726562,1844,741.9544067382812,1851.5,745.5789184570312C1866.9769287109375,753.0584106445312,1877.907958984375,750.9524536132812,1877.907958984375,750.9524536132812L1881,779.0789184570312L1881.5,783C1881.5,783,1880.772216796875,781.0933227539062,1880,780C1879.524658203125,779.3271484375,1878.9334716796875,779.2520141601562,1878.779052734375,779.2587280273438C1874.4549560546875,779.4468383789062,1864.1834716796875,779.14453125,1851.2255859375,773.7113647460938C1845.9761962890625,771.5103149414062,1838.35595703125,763.8938598632812,1834.5,756.9142456054688C1831,750.5789184570312,1827.9769287109375,742.6763305664062,1825.5,727.9142456054688C1824.5,721.9544067382812,1824,715.5076293945312,1824,706.0789184570312" + }, + "Union": { + vbX: 1654, vbY: 651, vbW: 98.865, vbH: 68.17, + d: "M1703.864990234375,681.8947143554688C1690.597412109375,681.9888305664062,1686.453857421875,683.7713012695312,1681,686.1704711914062C1673.953369140625,689.270263671875,1668.953857421875,691.7713012695312,1662,699.1704711914062C1656.837158203125,704.6639404296875,1654,719.1704711914062,1654,719.1704711914062C1654,719.1704711914062,1656.004150390625,700.2777709960938,1656.9522705078125,692.7372436523438C1657.953857421875,684.7713012695312,1659.453857421875,674.7713012695312,1662.519287109375,670.757568359375C1665.5238037109375,666.82373046875,1672.91650390625,659.1826171875,1680.62451171875,655.9833374023438C1685.953857421875,653.7713012695312,1696.9503173828125,651,1704.369140625,651C1710.957763671875,651,1720.4228515625,652.8333740234375,1726.240478515625,655.7075805664062C1733.453857421875,659.2713012695312,1741.102294921875,666.006103515625,1744.3455810546875,670.4818115234375C1747.453857421875,674.7713012695312,1748.953857421875,685.7713012695312,1749.91259765625,692.4614868164062C1750.81982421875,698.7919311523438,1752.864990234375,718.8947143554688,1752.864990234375,718.8947143554688C1752.864990234375,718.8947143554688,1749.953857421875,704.7713012695312,1744.864990234375,698.8947143554688C1738.8052978515625,691.897216796875,1731.953857421875,688.7713012695312,1725.864990234375,685.8947143554688C1718.756591796875,682.5364379882812,1716.50732421875,681.8049926757812,1703.864990234375,681.8947143554688" + } +}; diff --git a/index.html b/index.html new file mode 100644 index 0000000..347c0fd --- /dev/null +++ b/index.html @@ -0,0 +1,170 @@ + + + + + + Le Shed — Centre d'art contemporain en Normandie + + + + + + + +
+ + +
+ +
+
+

Le Shed

+

Centre d'art contemporain
en Normandie

+
+ +
+ +
+ + +
+

Expositions

+ +
+

The Underways

+
+ The Underways — Emmanuelle Antille +
+

Emmanuelle Antille

+

Exposition au Shed - La maison à Maromme du 7 février au 12 avril 2026

+
+ +
+

Rice Power

+
+ Rice Power — Yohan Thommerel +
+

Yohan Thommerel

+

Résidence au Shed - La maison à Maromme de 2024 à 2027

+
+ +
+

Hermine Bouvier

+
+ Hermine Bouvier +
+

dans la Project Room

+

Programme « Une chambre à soi »
au Shed - La maison à Maromme, 2025/2026

+
+ +
+

Arena

+
+ Arena — Combo Toys +
+

Combo Toys

+

Exposition au Shed - La maison à Maromme
du 7 février au 4 mars 2026

+
+ +
+ + +
+

Actions publiques

+ +
+
+

Vide-matrices

+
+ Vide-matrices +
+

+ Du 9 au 11 avril 2026 de 14h à 18h
+ les jeudis et vendredis de 10h à 18h le samedi
+ Au Shed - La maison à Maromme +

+
+ +
+

Appel à cueillir

+
+ Appel à cueillir +
+

+ Du 9 au 11 avril 2026 de 14h à 18h
+ les jeudis et vendredis de 10h à 18h le samedi
+ Au Shed - La maison à Maromme +

+
+ +
+

Danser au cœur
d'une exposition

+
+ Danser au cœur d'une exposition +
+

+ Samedi 28 mars 2026 de 9h30 à 11h30
+ Au Shed - La maison à Maromme +

+
+ +
+

Terres communes

+
+ Terres communes +
+

+ Samedi 17 mai 2026 de 14h à 18h
+ Atelier collectif en plein air
+ Au Shed - La maison à Maromme +

+
+
+ +
+ +
+ + + + + + + + + + + + diff --git a/objets.js b/objets.js new file mode 100644 index 0000000..e42b824 --- /dev/null +++ b/objets.js @@ -0,0 +1,96 @@ +/* ---------------------------------------------------------------- + Le Shed — Objets décoratifs + On place les 15 SVG d'objets pré-générés (assets/objets/objet-XX.svg) + à des positions choisies, avec des vitesses de parallax variées. + + Règle de placement : + - Bords (gauche/droite) du haut et du milieu → AU-DESSUS du contenu + - Centre de page (entre les colonnes) à partir du milieu → EN-DESSOUS + + Vitesses Rellax variées par objet pour un effet de profondeur. + ---------------------------------------------------------------- */ + +(function () { + + // Configuration des objets à placer. + // file : SVG à charger (1..15) + // x : décalage horizontal en pixels depuis 'side' + // y : position verticale en pixels depuis le haut du document + // side : 'left' | 'right' | 'center' (ancrage horizontal) + // size : taille (largeur) en pixels + // speed : vitesse Rellax (négative = plus rapide, positive = plus lente) + // layer : 'over' (au-dessus du contenu) | 'under' (en dessous) + var OBJETS = [ + // === HAUT — bords, au-dessus === + { file: 1, side: 'left', x: -50, y: 180, size: 392, speed: -2, layer: 'over' }, + { file: 3, side: 'right', x: -30, y: 380, size: 336, speed: 3, layer: 'over' }, + + // === MILIEU — bords, au-dessus, vitesses variées === + { file: 5, side: 'left', x: -40, y: 720, size: 308, speed: 1, layer: 'over' }, + { file: 7, side: 'right', x: -60, y: 950, size: 420, speed: -3, layer: 'over' }, + { file: 9, side: 'left', x: -30, y: 1280, size: 280, speed: 4, layer: 'over' }, + { file: 11, side: 'right', x: -20, y: 1480, size: 364, speed: -1, layer: 'over' }, + + // === MILIEU → BAS — vers le centre, EN-DESSOUS === + { file: 13, side: 'center', x: 0, y: 1750, size: 336, speed: 2, layer: 'under' }, + { file: 15, side: 'center', x: -120, y: 2050, size: 392, speed: -2, layer: 'under' }, + { file: 2, side: 'center', x: 100, y: 2300, size: 308, speed: 3, layer: 'under' } + ]; + + function createObjet(spec) { + var el = document.createElement('img'); + el.src = 'assets/objets/objet-' + String(spec.file).padStart(2, '0') + '.svg'; + el.alt = ''; + el.setAttribute('data-rellax-speed', spec.speed); + + el.style.position = 'absolute'; + el.style.width = spec.size + 'px'; + el.style.height = 'auto'; + el.style.top = spec.y + 'px'; + el.style.pointerEvents = 'none'; + el.style.userSelect = 'none'; + + if (spec.side === 'left') { + el.style.left = spec.x + 'px'; + } else if (spec.side === 'right') { + el.style.right = spec.x + 'px'; + } else { + // center : positionné à 50 % de la largeur viewport puis décalé + el.style.left = 'calc(50% + ' + spec.x + 'px)'; + el.style.transform = 'translateX(-50%)'; + } + + return el; + } + + function injectObjets() { + // Deux layers : "under" (z-index négatif) et "over" (z-index positif) + // chacune en position absolute, en visibilité overflow visible. + var layerUnder = document.createElement('div'); + layerUnder.className = 'objets-layer objets-layer--under'; + layerUnder.style.cssText = + 'position:absolute;inset:0;pointer-events:none;overflow:visible;z-index:-1'; + + var layerOver = document.createElement('div'); + layerOver.className = 'objets-layer objets-layer--over'; + layerOver.style.cssText = + 'position:absolute;inset:0;pointer-events:none;overflow:visible;z-index:20'; + + document.body.insertBefore(layerUnder, document.body.firstChild); + document.body.appendChild(layerOver); + + OBJETS.forEach(function (spec) { + var el = createObjet(spec); + if (spec.layer === 'under') { + layerUnder.appendChild(el); + } else { + layerOver.appendChild(el); + } + }); + + return Promise.resolve(); + } + + window.LeShedObjets = { inject: injectObjets }; + +})(); diff --git a/objets2-data.js b/objets2-data.js new file mode 100644 index 0000000..01423d7 --- /dev/null +++ b/objets2-data.js @@ -0,0 +1,25 @@ +/* Auto-generated — SVGs inlinés pour fonctionnement sans serveur */ +window.LeShedObjets2Data = { + "horizontaux/Group-10.svg": ``, + "horizontaux/Group-2.svg": ``, + "horizontaux/Group-3.svg": ``, + "horizontaux/Group-4.svg": ``, + "horizontaux/Group-5.svg": ``, + "horizontaux/Group-6.svg": ``, + "horizontaux/Group-7.svg": ``, + "horizontaux/Group-8.svg": ``, + "horizontaux/Group-9.svg": ``, + "horizontaux/Group.svg": ``, + "verticaux/Group-10.svg": ``, + "verticaux/Group-11.svg": ``, + "verticaux/Group-12.svg": ``, + "verticaux/Group-2.svg": ``, + "verticaux/Group-3.svg": ``, + "verticaux/Group-4.svg": ``, + "verticaux/Group-5.svg": ``, + "verticaux/Group-6.svg": ``, + "verticaux/Group-7.svg": ``, + "verticaux/Group-8.svg": ``, + "verticaux/Group-9.svg": ``, + "verticaux/Group.svg": `` +}; diff --git a/objets2.js b/objets2.js new file mode 100644 index 0000000..e31f2b8 --- /dev/null +++ b/objets2.js @@ -0,0 +1,161 @@ +/* ---------------------------------------------------------------- + Le Shed — Objets v5-bach + Charge les SVGs de assets/shapes/v5-bach, les inline dans le DOM, + et répartit leurs formes unitaires entre deux layers (under/over) + pour que chaque objet traverse le contenu. + + Horizontaux → côtés gauche et droit + Verticaux → centre (entre les colonnes) + + Chaque objet a 5 formes unitaires (index 0..4). + Formes 0,1,2 → layer under (z-index:-1) + Formes 3,4 → layer over (z-index:20) + ---------------------------------------------------------------- */ + +(function () { + + /* ---------------------------------------------------------------- + Catalogue de placement + side : 'left' | 'right' | 'center' + x : décalage depuis le bord (px, peut être négatif pour déborder) + y : position verticale depuis le haut du layout (px) + size : largeur cible en px (hauteur proportionnelle) + splitAt: index de la première forme qui passe en "over" (défaut: 3) + ---------------------------------------------------------------- */ + var CATALOGUE = [ + // --- Horizontaux gauche --- + { file: 'horizontaux/Group.svg', side: 'left', x: -100, y: 180, size: 255, speed: -1 }, + { file: 'horizontaux/Group-3.svg', side: 'left', x: -90, y: 550, size: 225, speed: 1.5 }, + { file: 'horizontaux/Group-6.svg', side: 'left', x: -110, y: 950, size: 270, speed: -1.5 }, + { file: 'horizontaux/Group-9.svg', side: 'left', x: -95, y: 1380, size: 240, speed: 1 }, + { file: 'horizontaux/Group-7.svg', side: 'left', x: -100, y: 1780, size: 245, speed: -1.5 }, + + // --- Horizontaux droite --- + { file: 'horizontaux/Group-2.svg', side: 'right', x: -90, y: 350, size: 270, speed: 1.5 }, + { file: 'horizontaux/Group-5.svg', side: 'right', x: -105, y: 750, size: 245, speed: -1 }, + { file: 'horizontaux/Group-8.svg', side: 'right', x: -95, y: 1150, size: 255, speed: 1 }, + { file: 'horizontaux/Group-10.svg', side: 'right', x: -100, y: 1580, size: 285, speed: -1.5 }, + { file: 'horizontaux/Group-4.svg', side: 'right', x: -90, y: 1950, size: 240, speed: 1.5 }, + + // --- Verticaux centre --- + { file: 'verticaux/Group.svg', side: 'center', x: -30, y: 280, size: 120, speed: 1 }, + { file: 'verticaux/Group-3.svg', side: 'center', x: 40, y: 650, size: 115, speed: -1.5 }, + { file: 'verticaux/Group-6.svg', side: 'center', x: -20, y: 1050, size: 125, speed: 1.5 }, + { file: 'verticaux/Group-9.svg', side: 'center', x: 35, y: 1450, size: 118, speed: -1 }, + { file: 'verticaux/Group-12.svg', side: 'center', x: -35, y: 1850, size: 120, speed: 1 }, + { file: 'verticaux/Group-4.svg', side: 'center', x: 25, y: 2200, size: 115, speed: -1.5 }, + ]; + + /* ---------------------------------------------------------------- + Parse un SVG depuis le dictionnaire inline (pas de fetch) + ---------------------------------------------------------------- */ + function loadSVG(key) { + var data = window.LeShedObjets2Data; + if (!data || !data[key]) { + console.warn('LeShedObjets2: SVG non trouvé:', key); + return Promise.resolve(null); + } + var parser = new DOMParser(); + var doc = parser.parseFromString(data[key], 'image/svg+xml'); + var svgEl = doc.querySelector('svg'); + if (!svgEl) return Promise.resolve(null); + var topG = svgEl.querySelector('svg > g'); + if (!topG) return Promise.resolve(null); + var shapes = Array.from(topG.children).filter(function (c) { + return c.tagName === 'g'; + }); + return Promise.resolve({ svgEl: svgEl, shapes: shapes }); + } + + /* ---------------------------------------------------------------- + Crée un clone avec les formes données, positionné en absolute + ---------------------------------------------------------------- */ + function makeSVGFragment(sourceSVG, shapes, spec, naturalW, naturalH) { + var targetW = spec.size; + var targetH = Math.round(naturalH * (targetW / naturalW)); + + var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + svg.setAttribute('viewBox', '0 0 ' + naturalW + ' ' + naturalH); + svg.setAttribute('width', targetW); + svg.setAttribute('height', targetH); + svg.setAttribute('fill', 'none'); + if (spec.speed !== undefined) svg.setAttribute('data-rellax-speed', spec.speed); + svg.style.cssText = 'position:absolute;pointer-events:none;'; + + // Position horizontale + if (spec.side === 'left') { + svg.style.left = spec.x + 'px'; + } else if (spec.side === 'right') { + svg.style.right = spec.x + 'px'; + } else { + // center : centré entre les colonnes (centre de la page) + svg.style.left = '50%'; + svg.style.marginLeft = (spec.x - targetW / 2) + 'px'; + } + svg.style.top = spec.y + 'px'; + + // Copie les defs si présents + var defs = sourceSVG.querySelector('defs'); + if (defs) svg.appendChild(defs.cloneNode(true)); + + shapes.forEach(function (g) { + svg.appendChild(g.cloneNode(true)); + }); + + return svg; + } + + /* ---------------------------------------------------------------- + Inject principal + ---------------------------------------------------------------- */ + function injectObjets2() { + var layout = document.querySelector('.layout'); + if (!layout) return Promise.resolve(); + + // Layer under : position absolute dans le layout, z-index négatif + var layerUnder = document.createElement('div'); + layerUnder.className = 'objets2-layer objets2-layer--under'; + layerUnder.style.cssText = + 'position:absolute;inset:0;pointer-events:none;overflow:visible;z-index:-1'; + + // Layer over : position absolute dans le layout, z-index positif + var layerOver = document.createElement('div'); + layerOver.className = 'objets2-layer objets2-layer--over'; + layerOver.style.cssText = + 'position:absolute;inset:0;pointer-events:none;overflow:visible;z-index:20'; + + // Insérer avant le contenu pour que le z-index fonctionne + layout.insertBefore(layerUnder, layout.firstChild); + layout.appendChild(layerOver); + + var promises = CATALOGUE.map(function (spec) { + return loadSVG(spec.file).then(function (result) { + if (!result) return; + var shapes = result.shapes; + var svgEl = result.svgEl; + var naturalW = parseFloat(svgEl.getAttribute('width')); + var naturalH = parseFloat(svgEl.getAttribute('height')); + var splitAt = spec.splitAt !== undefined ? spec.splitAt : 3; + + var shapesUnder = shapes.slice(0, splitAt); + var shapesOver = shapes.slice(splitAt); + + if (shapesUnder.length) { + layerUnder.appendChild( + makeSVGFragment(svgEl, shapesUnder, spec, naturalW, naturalH) + ); + } + if (shapesOver.length) { + layerOver.appendChild( + makeSVGFragment(svgEl, shapesOver, spec, naturalW, naturalH) + ); + } + }); + }); + + return Promise.all(promises); + } + + window.LeShedObjets2 = { inject: injectObjets2 }; + +}()); diff --git a/paysage.js b/paysage.js new file mode 100644 index 0000000..358d5a9 --- /dev/null +++ b/paysage.js @@ -0,0 +1,390 @@ +/* ---------------------------------------------------------------- + Le Shed — Paysage de formes élémentaires + Système décoratif indépendant de objets.js. + Place des formes SVG individuelles en strates horizontales + (ciel → horizon → lointain → moyen plan → premier plan) + avec parallax custom (pas Rellax) et répartition organique (Perlin). + + Les formes vivent dans un wrapper position:fixed + overflow:hidden + pour ne jamais influencer le scrollHeight du document. + ---------------------------------------------------------------- */ + +(function () { + + /* ============================================================ + PERLIN NOISE 2D (simplifié, 2 octaves) + ============================================================ */ + + var PERLIN_SIZE = 256; + var perm = []; + + function initPerlin(seed) { + var p = []; + for (var i = 0; i < PERLIN_SIZE; i++) p[i] = i; + var s = seed || 42; + for (var i = PERLIN_SIZE - 1; i > 0; i--) { + s = (s * 16807 + 0) % 2147483647; + var j = s % (i + 1); + var tmp = p[i]; p[i] = p[j]; p[j] = tmp; + } + perm = []; + for (var i = 0; i < 512; i++) perm[i] = p[i & 255]; + } + + function fade(t) { return t * t * t * (t * (t * 6 - 15) + 10); } + function lerp(a, b, t) { return a + t * (b - a); } + + var grad3 = [[1,1],[-1,1],[1,-1],[-1,-1],[1,0],[-1,0],[0,1],[0,-1]]; + + function dot2(g, x, y) { return g[0] * x + g[1] * y; } + + function perlin2(x, y) { + var X = Math.floor(x) & 255, Y = Math.floor(y) & 255; + x -= Math.floor(x); y -= Math.floor(y); + var u = fade(x), v = fade(y); + var aa = perm[perm[X] + Y], ab = perm[perm[X] + Y + 1]; + var ba = perm[perm[X + 1] + Y], bb = perm[perm[X + 1] + Y + 1]; + return lerp( + lerp(dot2(grad3[aa & 7], x, y), dot2(grad3[ba & 7], x - 1, y), u), + lerp(dot2(grad3[ab & 7], x, y - 1), dot2(grad3[bb & 7], x - 1, y - 1), u), + v + ); + } + + function perlinOctaves(x, y, octaves) { + var val = 0, amp = 1, freq = 1, max = 0; + for (var i = 0; i < octaves; i++) { + val += perlin2(x * freq, y * freq) * amp; + max += amp; + amp *= 0.5; + freq *= 2; + } + return (val / max + 1) / 2; + } + + /* ============================================================ + SEEDED RANDOM + ============================================================ */ + + var rngState = 12345; + function seedRng(s) { rngState = s; } + function rng() { + rngState = (rngState * 16807 + 0) % 2147483647; + return (rngState - 1) / 2147483646; + } + function rngInt(min, max) { return Math.floor(rng() * (max - min + 1)) + min; } + function rngFloat(min, max) { return rng() * (max - min) + min; } + function rngPick(arr) { return arr[rngInt(0, arr.length - 1)]; } + + /* ============================================================ + VOCABULAIRE PAR REGISTRE + ============================================================ */ + + var REGISTRES = { + nuages: ['Rectangle-6', 'Rectangle-8', 'Rectangle-9', 'Union'], + ciel_legers: ['Path-10', 'Union-2', 'Union'], + horizon: ['Path-2', 'Path-4', 'Rectangle-7'], + lointain: ['Path-3', 'Path-9', 'Rectangle', 'Path-2'], + verticales: ['Path-3', 'Path-8', 'Path-9', 'Rectangle', 'Rectangle-2'], + obliques_moyennes: ['Path-5', 'Path-6', 'Rectangle-3', 'Rectangle-4'], + obliques_longues: ['Path-7', 'Rectangle-5', 'Path'], + masses: ['Path', 'Rectangle-3', 'Rectangle-9'], + details_sol: ['Path-10', 'Path-3', 'Rectangle'] + }; + + /* ============================================================ + COLLISION DETECTION + ============================================================ */ + + var MARGIN = 0.8; + var placed = []; + + function collides(x, y, w, h) { + var ax1 = x - MARGIN, ay1 = y - MARGIN; + var ax2 = x + w + MARGIN, ay2 = y + h + MARGIN; + for (var i = 0; i < placed.length; i++) { + var b = placed[i]; + if (ax1 < b.x2 && ax2 > b.x1 && ay1 < b.y2 && ay2 > b.y1) return true; + } + return false; + } + + function addPlaced(x, y, w, h) { + placed.push({ x1: x, x2: x + w, y1: y, y2: y + h }); + } + + /* ============================================================ + SVG ELEMENT CREATION (no data-rellax-speed — parallax is manual) + ============================================================ */ + + // All placed shapes for manual parallax + var allShapes = []; + + function createSvgShape(shapeName, x, y, scale, speed) { + var data = window.LeShedFormesElementaires[shapeName]; + if (!data) return null; + + var ns = 'http://www.w3.org/2000/svg'; + var svg = document.createElementNS(ns, 'svg'); + var w = data.vbW * scale; + var h = data.vbH * scale; + + svg.setAttribute('viewBox', data.vbX + ' ' + data.vbY + ' ' + data.vbW + ' ' + data.vbH); + svg.setAttribute('width', w); + svg.setAttribute('height', h); + svg.setAttribute('fill', 'none'); + + var path = document.createElementNS(ns, 'path'); + path.setAttribute('d', data.d); + path.setAttribute('fill', 'black'); + svg.appendChild(path); + + svg.style.position = 'absolute'; + svg.style.left = x + 'px'; + svg.style.pointerEvents = 'none'; + svg.style.userSelect = 'none'; + svg.style.willChange = 'transform'; + + // Store for parallax loop + allShapes.push({ el: svg, baseY: y, speed: speed }); + + return { el: svg, w: w, h: h }; + } + + /* ============================================================ + PLACEMENT STRATEGIES + ============================================================ */ + + function tryPlace(shapeName, x, y, scale, speed, layerEl) { + var data = window.LeShedFormesElementaires[shapeName]; + if (!data) return false; + var w = data.vbW * scale; + var h = data.vbH * scale; + if (collides(x, y, w, h)) return false; + + var result = createSvgShape(shapeName, x, y, scale, speed); + if (!result) return false; + layerEl.appendChild(result.el); + addPlaced(x, y, w, h); + return true; + } + + function placeCluster(shapes, cx, cy, radius, count, scale, speedRange, layerEl, pageW) { + var placedCount = 0; + var attempts = 0; + while (placedCount < count && attempts < count * 8) { + attempts++; + var angle = rng() * Math.PI * 2; + var dist = rng() * radius; + var x = cx + Math.cos(angle) * dist; + var y = cy + Math.sin(angle) * dist; + if (x < 0 || x > pageW) continue; + var shape = rngPick(shapes); + var speed = rngFloat(speedRange[0], speedRange[1]); + if (tryPlace(shape, x, y, scale, Math.round(speed), layerEl)) { + placedCount++; + } + } + return placedCount; + } + + /* ============================================================ + PARALLAX SCROLL LOOP + ============================================================ */ + + function startParallaxLoop() { + var ticking = false; + + function update() { + var scrollY = window.scrollY; + for (var i = 0; i < allShapes.length; i++) { + var s = allShapes[i]; + // Position dans le viewport sans parallax : baseY - scrollY + // Parallax : décalage doux proportionnel au scroll, comme Rellax + // Rellax fait environ speed * scrollY / 10 + var basePos = s.baseY - scrollY; + var parallaxOffset = s.speed * scrollY * 0.1; + s.el.style.transform = 'translateY(' + Math.round(basePos + parallaxOffset) + 'px)'; + } + ticking = false; + } + + window.addEventListener('scroll', function () { + if (!ticking) { + ticking = true; + requestAnimationFrame(update); + } + }, { passive: true }); + + // Initial position + update(); + } + + /* ============================================================ + MAIN INJECTION + ============================================================ */ + + function injectPaysage() { + if (!window.LeShedFormesElementaires) { + console.warn('LeShedPaysage: formes-elementaires-data.js not loaded'); + return Promise.resolve(); + } + + var seed = Math.floor(Math.random() * 100000); + seedRng(seed); + initPerlin(seed); + placed = []; + allShapes = []; + + var pageW = window.innerWidth; + // Hauteur basée sur la plus courte colonne (la page ne scrolle pas au-delà) + var colLeft = document.querySelector('.col--left'); + var colRight = document.querySelector('.col--right'); + var layoutEl = document.querySelector('.layout'); + var minColH = Math.min( + colLeft ? colLeft.offsetHeight : 2000, + colRight ? colRight.offsetHeight : 2000 + ); + var docH = (layoutEl ? layoutEl.offsetTop : 100) + minColH; + var scale = Math.max(0.12, pageW / 3000); + + // Horizon line varies per load + var horizonRatio = rngFloat(0.38, 0.55); + var horizonY = docH * horizonRatio; + + // Strate boundaries + var SAFE_TOP = 120; + var cielTop = SAFE_TOP; + var cielBottom = horizonY - 30; + var horizonTop = horizonY - 15; + var horizonBottom = horizonY + 15; + var lointainTop = horizonY + 15; + var lointainBottom = horizonY + 55; + var moyenTop = horizonY + 55; + var moyenBottom = horizonY + 120; + var premierTop = horizonY + 120; + var premierBottom = docH - 100; + + // Deux wrappers fixed séparés pour que les z-index s'intercalent + // avec le contenu (z-index 5 pour .layout) + var layerUnder = document.createElement('div'); + layerUnder.className = 'paysage-layer paysage-layer--under'; + layerUnder.style.cssText = + 'position:fixed;top:0;left:0;width:100%;height:100vh;pointer-events:none;overflow:hidden;z-index:-1'; + + var layerOver = document.createElement('div'); + layerOver.className = 'paysage-layer paysage-layer--over'; + layerOver.style.cssText = + 'position:fixed;top:0;left:0;width:100%;height:100vh;pointer-events:none;overflow:hidden;z-index:30'; + + document.body.appendChild(layerUnder); + document.body.appendChild(layerOver); + + function pickLayer(band) { + var underChance; + if (band === 'ciel' || band === 'lointain') underChance = 0.7; + else if (band === 'premier') underChance = 0.3; + else underChance = 0.5; + return rng() < underChance ? layerUnder : layerOver; + } + + function speedForBand(band) { + if (band === 'ciel') return rngFloat(1, 4); + if (band === 'horizon') return rngFloat(0, 3); + if (band === 'lointain') return rngFloat(0, 3); + if (band === 'moyen') return rngFloat(-2, 2); + return rngFloat(-4, -1); + } + + /* ---- CIEL ---- */ + var cloudClusters = rngInt(2, 4); + for (var i = 0; i < cloudClusters; i++) { + var cx = rngFloat(pageW * 0.1, pageW * 0.9); + var cy = rngFloat(cielTop, cielBottom * 0.6); + placeCluster(REGISTRES.nuages, cx, cy, + rngFloat(40, 100) * scale * 10, rngInt(2, 4), scale, + [1, 4], pickLayer('ciel'), pageW); + } + + var cielIsolated = rngInt(3, 7); + for (var i = 0; i < cielIsolated; i++) { + var x = rngFloat(0, pageW); + var y = rngFloat(cielTop, cielBottom); + tryPlace(rngPick(REGISTRES.ciel_legers), x, y, scale, + Math.round(speedForBand('ciel')), pickLayer('ciel')); + } + + /* ---- HORIZON ---- */ + var horizonCount = rngInt(1, 3); + for (var i = 0; i < horizonCount; i++) { + tryPlace(rngPick(REGISTRES.horizon), rngFloat(0, pageW * 0.7), + rngFloat(horizonTop, horizonBottom), scale, + Math.round(speedForBand('horizon')), pickLayer('horizon')); + } + + /* ---- LOINTAIN ---- */ + var perlinScale = 0.02 / scale; + for (var i = 0; i < 80; i++) { + var x = rngFloat(0, pageW); + var y = rngFloat(lointainTop, lointainBottom); + if (perlinOctaves(x * perlinScale, y * perlinScale, 2) < 0.4) continue; + tryPlace(rngPick(REGISTRES.lointain), x, y, scale, + Math.round(speedForBand('lointain')), pickLayer('lointain')); + } + + /* ---- MOYEN PLAN ---- */ + for (var i = 0; i < rngInt(3, 6); i++) { + placeCluster(REGISTRES.verticales, + rngFloat(pageW * 0.05, pageW * 0.95), rngFloat(moyenTop, moyenBottom), + rngFloat(12, 22) * scale * 10, rngInt(4, 9), scale, + [-2, 2], pickLayer('moyen'), pageW); + } + for (var i = 0; i < rngInt(2, 5); i++) { + placeCluster(REGISTRES.obliques_moyennes, + rngFloat(pageW * 0.1, pageW * 0.9), rngFloat(moyenTop, moyenBottom), + rngFloat(15, 25) * scale * 10, rngInt(2, 4), scale, + [-2, 2], pickLayer('moyen'), pageW); + } + for (var i = 0; i < rngInt(1, 3); i++) { + tryPlace(rngPick(REGISTRES.nuages), + rngFloat(0, pageW * 0.8), rngFloat(moyenTop, moyenBottom), scale, + Math.round(rngFloat(-1, 2)), pickLayer('moyen')); + } + + /* ---- PREMIER PLAN ---- */ + for (var i = 0; i < rngInt(1, 3); i++) { + tryPlace(rngPick(REGISTRES.obliques_longues), + rngFloat(0, pageW * 0.6), rngFloat(premierTop, premierBottom * 0.8), scale, + Math.round(speedForBand('premier')), pickLayer('premier')); + } + for (var i = 0; i < rngInt(6, 11); i++) { + var shapes = rng() > 0.5 ? REGISTRES.verticales : REGISTRES.details_sol; + placeCluster(shapes, + rngFloat(pageW * 0.02, pageW * 0.98), rngFloat(premierTop, premierBottom * 0.95), + rngFloat(10, 20) * scale * 10, rngInt(5, 12), scale, + [-4, -1], pickLayer('premier'), pageW); + } + for (var i = 0; i < rngInt(2, 4); i++) { + placeCluster(REGISTRES.masses, + rngFloat(pageW * 0.05, pageW * 0.95), rngFloat(premierTop, premierBottom * 0.9), + rngFloat(20, 35) * scale * 10, rngInt(2, 4), scale, + [-4, -1], pickLayer('premier'), pageW); + } + for (var i = 0; i < 150; i++) { + var x = rngFloat(0, pageW); + var y = rngFloat(premierTop, premierBottom * 0.95); + if (perlinOctaves(x * perlinScale, y * perlinScale, 2) < 0.35) continue; + var allPremier = REGISTRES.verticales.concat(REGISTRES.details_sol, REGISTRES.masses); + tryPlace(rngPick(allPremier), x, y, scale, + Math.round(speedForBand('premier')), pickLayer('premier')); + } + + // Start manual parallax loop + startParallaxLoop(); + + return Promise.resolve(); + } + + window.LeShedPaysage = { inject: injectPaysage }; + +})(); diff --git a/style.css b/style.css new file mode 100644 index 0000000..be213dc --- /dev/null +++ b/style.css @@ -0,0 +1,293 @@ +/* ---------------------------------------------------------------- + Le Shed — Centre d'art contemporain en Normandie + Maquette desktop avec parallax différentiel entre colonnes + ---------------------------------------------------------------- */ + +@font-face { + font-family: 'BVH'; + src: url('assets/fonts/BVHAntoPlotTrial-LightItalic.otf') format('opentype'); + font-weight: 300; + font-style: italic; + font-display: swap; +} + +:root { + --color-bg: #ffffff; + --color-ink: #000000; + --motif-color: #000000; + --color-mute: #6a6a6a; + --color-light: #9a9a9a; + + --font-display: 'BVH', 'Inter', serif; + --font-body: 'Inter', system-ui, sans-serif; + + --page-pad-x: 80px; + --page-pad-y: 28px; + --col-gap: 64px; + + /* (réservé) */ +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html, body { + background: var(--color-bg); + color: var(--color-ink); + font-family: var(--font-body); + font-size: 15px; + line-height: 1.45; + -webkit-font-smoothing: antialiased; +} + +body { + overflow-x: hidden; + /* Stacking context sans position:relative pour éviter que les layers + absolues du paysage n'étirent le scrollHeight */ + isolation: isolate; +} + +img { + display: block; + max-width: 100%; + height: auto; +} + +/* -------- Couleur motifs -------- */ + +.objets-layer path, +.objets2-layer path, +.paysage-layer path { + fill: var(--motif-color) !important; +} + +/* -------- Settings -------- */ + +.settings { + position: fixed; + top: 16px; + left: 16px; + z-index: 200; + display: none; +} + +.settings__btn { + background: none; + border: none; + font-size: 16px; + cursor: pointer; + opacity: 0.35; + padding: 4px; + transition: opacity 0.15s ease; + line-height: 1; +} + +.settings__btn:hover { + opacity: 1; +} + +.settings__panel { + margin-top: 6px; + background: var(--color-bg); + border: 1px solid #e0e0e0; + padding: 12px 14px; + display: flex; + flex-direction: column; + gap: 8px; + min-width: 120px; +} + +.settings__panel[hidden] { + display: none; +} + +.settings__label { + font-size: 11px; + color: var(--color-mute); + letter-spacing: 0.05em; + text-transform: uppercase; + margin-bottom: 2px; +} + +.settings__option { + font-size: 13px; + cursor: pointer; + display: flex; + align-items: center; + gap: 7px; +} + +/* -------- Masthead -------- */ + +.masthead { + position: fixed; + top: 0; + left: 0; + right: 0; + display: flex; + justify-content: space-between; + align-items: flex-start; + max-width: 1000px; + margin-inline: auto; + padding: var(--page-pad-y) var(--page-pad-x); + z-index: 100; + background: var(--color-bg); + transition: padding 0.3s ease; +} + +.layout { + position: relative; + display: grid; + grid-template-columns: 1fr 1fr; + column-gap: var(--col-gap); + max-width: 1000px; + margin-inline: auto; + padding: 36px var(--page-pad-x) 36px; + align-items: start; + z-index: 5; +} + +.brand__title { + font-family: var(--font-display); + font-weight: 300; + font-size: 28px; + line-height: 1; + letter-spacing: 0.01em; +} + +.brand__sub { + font-size: 11px; + color: var(--color-mute); + margin-top: 4px; + line-height: 1.35; + transition: opacity 0.3s ease, max-height 0.3s ease, margin-top 0.3s ease; + max-height: 3em; + overflow: hidden; +} + +.masthead.is-compact { + padding-bottom: 10px; +} + +.masthead.is-compact .brand__sub { + opacity: 0; + max-height: 0; + margin-top: 0; +} + +.nav { + display: flex; + gap: 36px; + padding-top: 8px; +} + +.nav a { + color: var(--color-ink); + text-decoration: none; + font-size: 14px; + font-weight: 400; + transition: opacity 0.18s ease; +} + +.nav a:hover { + opacity: 0.5; +} + +/* -------- Colonnes -------- */ + +.col { + position: relative; + display: flex; + flex-direction: column; + gap: 0; +} + +.col > .card + .card, +.col__cards > .card + .card { + margin-top: 56px; +} + +.col__heading { + position: sticky; + top: var(--header-h, 80px); + font-size: 13px; + font-weight: 400; + color: var(--color-mute); + letter-spacing: 0.01em; + z-index: 10; + background: var(--color-bg); + padding: 8px 0 0; + --col-heading-h: 35px; +} + +.col--left > .col__heading { + width: calc(100% + 64px); +} + +.col__cards { + display: flex; + flex-direction: column; + margin-top: 0; + padding-top: 0; +} + +/* -------- Cards -------- */ + +.card { + display: flex; + flex-direction: column; +} + +.card__media { + margin-bottom: 18px; + overflow: hidden; + transition: scale 0.3s ease; +} + +.card__media img { + width: 100%; + height: auto; + object-fit: cover; +} + +.card__title { + position: sticky; + top: calc(var(--header-h, 80px) + var(--col-heading-h, 35px) - 2px); + font-family: var(--font-display); + font-weight: 300; + font-size: 44px; + line-height: 1; + margin-bottom: 6px; + color: var(--color-ink); + z-index: 5; + background: var(--color-bg); + padding: 8px 0; + transition: font-size 0.3s ease; +} + +/* Hover carte */ +.card { + cursor: pointer; +} +.card:hover > .card__title { + font-size: 42.7px; +} +.card:hover > .card__media { + scale: 0.97; +} + +.card__author { + font-size: 15px; + font-weight: 400; + color: var(--color-ink); + margin-bottom: 4px; +} + +.card__meta { + font-size: 13px; + color: var(--color-mute); + line-height: 1.45; +}