5 Commits
17 changed files with 5421 additions and 44 deletions
File diff suppressed because it is too large Load Diff
+631
View File
@@ -0,0 +1,631 @@
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'html' -->
<!-- FILE NAME SUGGESTIONS:
▪️ html--node--570.html.twig
▪️ html--node--%.html.twig
▪️ html--node.html.twig
✅ html.html.twig
-->
<!-- 💡 BEGIN CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/html.html.twig' -->
<!DOCTYPE html>
<html lang="fr" dir="ltr">
<head>
<meta charset="utf-8" />
<meta name="Generator" content="Drupal 10 (https://www.drupal.org)" />
<meta name="MobileOptimized" content="width" />
<meta name="HandheldFriendly" content="true" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="/core/misc/favicon.ico" type="image/vnd.microsoft.icon" />
<link rel="alternate" hreflang="fr" href="http://dev.leshed.fr/node/570" />
<link rel="canonical" href="http://dev.leshed.fr/node/570" />
<link rel="shortlink" href="http://dev.leshed.fr/node/570" />
<title>FAGO | Le Shed</title>
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/align.module.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/fieldgroup.module.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/container-inline.module.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/clearfix.module.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/details.module.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/hidden.module.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/item-list.module.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/js.module.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/nowrap.module.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/position-container.module.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/reset-appearance.module.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/resize.module.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/system-status-counter.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/system-status-report-counters.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/system-status-report-general-info.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/core/modules/system/css/components/tablesort.module.css?tjtjpd" />
<link rel="stylesheet" media="all" href="/modules/contrib/extlink/css/extlink.css?tjtjpd" />
</head>
<body>
<a href="#main-content" class="visually-hidden focusable">
Aller au contenu principal
</a>
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'off_canvas_page_wrapper' -->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/off-canvas-page-wrapper.html.twig' -->
<div class="dialog-off-canvas-main-canvas" data-off-canvas-main-canvas>
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'page' -->
<!-- FILE NAME SUGGESTIONS:
▪️ page--node--570.html.twig
▪️ page--node--%.html.twig
▪️ page--node.html.twig
✅ page.html.twig
-->
<!-- 💡 BEGIN CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/page.html.twig' -->
<div class="layout-container">
<header role="banner">
<section class="header-top"></section>
<section class="header-middle">
<section class="header-left">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'region' -->
<!-- FILE NAME SUGGESTIONS:
▪️ region--header-left.html.twig
✅ region.html.twig
-->
<!-- 💡 BEGIN CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/region.html.twig' -->
<div class="wrapper">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'block' -->
<!-- FILE NAME SUGGESTIONS:
▪️ block--leshed-identitedusite.html.twig
✅ block--system-branding-block.html.twig
▪️ block--system.html.twig
▪️ block.html.twig
-->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/block--system-branding-block.html.twig' -->
<div id="block-leshed-identitedusite">
<a href="/" rel="home">Le Shed</a>
Centre d'art en Normandie
</div>
<!-- END OUTPUT from 'core/modules/system/templates/block--system-branding-block.html.twig' -->
</div>
<!-- END CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/region.html.twig' -->
</section>
<section class="header-center"></section>
<section class="header-right">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'region' -->
<!-- FILE NAME SUGGESTIONS:
✅ region--header-right.html.twig
▪️ region.html.twig
-->
<!-- 💡 BEGIN CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/region--header-right.html.twig' -->
<div id="burger-btn"></div>
<div class="wrapper">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'block' -->
<!-- FILE NAME SUGGESTIONS:
▪️ block--leshed-navigationprincipale.html.twig
▪️ block--menu-block--main.html.twig
▪️ block--menu-block.html.twig
✅ block--system-menu-block.html.twig
▪️ block.html.twig
-->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/block--system-menu-block.html.twig' -->
<nav role="navigation" aria-labelledby="block-leshed-navigationprincipale-menu" id="block-leshed-navigationprincipale">
<h2 class="visually-hidden" id="block-leshed-navigationprincipale-menu">Navigation principale</h2>
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'menu' -->
<!-- FILE NAME SUGGESTIONS:
▪️ menu--main.html.twig
✅ menu.html.twig
-->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/menu.html.twig' -->
<ul>
<li>
<a href="/" data-drupal-link-system-path="&lt;front&gt;">Accueil</a>
</li>
</ul>
<!-- END OUTPUT from 'core/modules/system/templates/menu.html.twig' -->
</nav>
<!-- END OUTPUT from 'core/modules/system/templates/block--system-menu-block.html.twig' -->
</div>
<!-- END CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/region--header-right.html.twig' -->
</section>
</section>
<section class="header-bottom"></section>
</header>
<nav role="breadcrumb">
</nav>
<main role="main">
<a id="main-content" tabindex="-1"></a>
<div class="layout-content">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'region' -->
<!-- FILE NAME SUGGESTIONS:
▪️ region--content.html.twig
✅ region.html.twig
-->
<!-- 💡 BEGIN CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/region.html.twig' -->
<div class="wrapper">
<div data-drupal-messages-fallback class="hidden"></div>
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'node' -->
<!-- FILE NAME SUGGESTIONS:
▪️ node--570--full.html.twig
▪️ node--570.html.twig
✅ node--projet--full.html.twig
▪️ node--projet.html.twig
▪️ node--full.html.twig
▪️ node.html.twig
-->
<!-- 💡 BEGIN CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/node--projet--full.html.twig' -->
<article class="node-type-projet view-mode-full">
<div class="cols">
<div class="col left">
<h2>
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'field' -->
<!-- FILE NAME SUGGESTIONS:
▪️ field--node--title--projet.html.twig
✅ field--node--title.html.twig
▪️ field--node--projet.html.twig
▪️ field--title.html.twig
▪️ field--string.html.twig
▪️ field.html.twig
-->
<!-- BEGIN OUTPUT from 'core/modules/node/templates/field--node--title.html.twig' -->
<span class="title">FAGO</span>
<!-- END OUTPUT from 'core/modules/node/templates/field--node--title.html.twig' -->
</h2>
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'field' -->
<!-- FILE NAME SUGGESTIONS:
▪️ field--node--field-artiste-s-invite-s--projet.html.twig
▪️ field--node--field-artiste-s-invite-s.html.twig
▪️ field--node--projet.html.twig
▪️ field--field-artiste-s-invite-s.html.twig
▪️ field--entity-reference.html.twig
✅ field.html.twig
-->
<!-- 💡 BEGIN CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/field.html.twig' -->
<div class="field_artiste_s_invite_s field-items multiple">
<div class="field-item"><a href="/node/569" hreflang="fr">Géraldine Longueville</a></div>
</div>
<!-- END CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/field.html.twig' -->
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'field' -->
<!-- FILE NAME SUGGESTIONS:
▪️ field--node--field-invite-accompagne-curate-p--projet.html.twig
▪️ field--node--field-invite-accompagne-curate-p.html.twig
▪️ field--node--projet.html.twig
▪️ field--field-invite-accompagne-curate-p.html.twig
▪️ field--entity-reference.html.twig
✅ field.html.twig
-->
<!-- 💡 BEGIN CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/field.html.twig' -->
<div class="field_invite_accompagne_curate_p">
<div class="field-label">invite/accompagné/curaté par</div>
<div class="field-items multiple">
<div class="field-item"><a href="/node/508" hreflang="fr">Virginie Bobin</a></div>
</div>
</div>
<!-- END CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/field.html.twig' -->
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'field' -->
<!-- FILE NAME SUGGESTIONS:
▪️ field--node--field-dates--projet.html.twig
▪️ field--node--field-dates.html.twig
▪️ field--node--projet.html.twig
▪️ field--field-dates.html.twig
▪️ field--daterange.html.twig
✅ field.html.twig
-->
<!-- 💡 BEGIN CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/field.html.twig' -->
<div class="field_dates field-item">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'time' -->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/time.html.twig' -->
<time datetime="2026-06-28T12:00:00Z">28 juin 2026</time>
<!-- END OUTPUT from 'core/modules/system/templates/time.html.twig' -->
-
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'time' -->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/time.html.twig' -->
<time datetime="2026-09-27T12:00:00Z">27 Sep 2026</time>
<!-- END OUTPUT from 'core/modules/system/templates/time.html.twig' -->
</div>
<!-- END CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/field.html.twig' -->
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'field' -->
<!-- FILE NAME SUGGESTIONS:
▪️ field--node--body--projet.html.twig
▪️ field--node--body.html.twig
▪️ field--node--projet.html.twig
▪️ field--body.html.twig
▪️ field--text-with-summary.html.twig
✅ field.html.twig
-->
<!-- 💡 BEGIN CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/field.html.twig' -->
<div class="body field-item"><p>De lAlgérie à la Normandie en passant par le Japon, lartiste et cueilleuse Géraldine Longueville retrace les trajectoires entremêlées de plantes et de corps pris dans les mailles de récits intimes et politiques, notamment liés à lhistoire coloniale. Spécialement produites pour lexposition, les œuvres présentées (installations, film, pièce sonore) composent un jardin à la fois mémoriel et fabuleux, fruit de gestes, de processus et dhistoires transmises par lartiste lors dateliers et de performances. Cueillies, séchées, nouées, consumées ou macérées, les plantes déposées dans les pièces de La maison accueillant le Shed à Maromme en appellent à tous nos sens. Entre amertume et guérison, elles invitent à se rassembler autour delles le temps dune boisson ou dune chanson.</p>
<p><em>Fago</em> est lultime étape des recherches menées par Géraldine Longueville dans le cadre du programme doctoral RADIAN (ésam Caen-Cherbourg, ésadhar, ENSA Normandie et Normandie-Université).</p>
<p>Une exposition curatée par Virginie Bobin Dans le cadre de Normandie Impressionniste</p>
<p>Assistant artistique : Alioun Abderrahmane</p>
<h1>Géraldine Longueville</h1>
<p>Diplômée dun Master Fine Arts de Sandberg Institute à Amsterdam et dun Master Histoire de lArt de la Sorbonne Université Paris, elle poursuit actuellement une thèse en Recherche et Créationu sein du programme Radian (ésam Caen-Cherbourg, ésadhar, ENSA Normandie et Normandie-Université). Elle a travaillé dans des centres dart contemporains franciliens (Emba Manet Gennevilliers, La Galerie Noisy-le-Sec) et à l’école nationale darts Paris-Cergy (ENSAPC). Depuis 2016, elle enseigne la performance et l’écriture à lEcole Européenne Supérieure de lImage de Poitiers (EESI).</p>
<p>Sa pratique artistique est transversale, mêlant écriture, chant, musique, comestible et installation. Elle se déploie à travers différentes formes de collaborations et de partage tant avec les artistes que le public. La circulation des savoirs écologiques et leurs transmissions sensorielles sur site sont au cœur de ses productions. En 2019, elle se forme aux jardins des plantes médicinales au Potager du Roi à l'École nationale supérieure du paysage à Versailles et elle suit la formation du cueilleur.euse.s Le chemin de la nature de Christophe de Hody.<br>
Pendant une vingtaine d'années, elle a mené de nombreux projets collectifs : membre de Glassbox en 2002, elle a monté la galerie extérieure en 2005, projet d'intervention artistique dans lespace public à Paris et aux Etats-Unis. En 2011, avec les artistes David Bersntein et Jurgis Paskevicius, elle crée le trio Jugedamos avec lequel elle réalise de nombreuses performances à Amsterdam (De Appel), New-York (Sculpture Center) ou Rome (Nomas Foundation). De retour à Paris en 2014, avec la cheffe Virginie Galan et les designers graphiques Commune, elle cofonde Black Garlic, un atelier en art et gastronomie qui organise des dîners dans des brasseries et des lieux darts.<br>
Depuis 2017, elle travaille sur des projets personnels incluants des invitations collaboratives qui sont exposés au Cac Bretigny, Bétonsalon Paris, galerie gb agency Paris, Goethe Institut Nancy, Kyoto art center, galerie Jocelyn Wolff Paris et la Grande Galerie de l’ésam de Caen.<br>
Elle mène depuis 2019 une recherche sur lamertume, goût et sentiment qui selon elle traduisent la persistance du colonialisme et la résistance à la colonialité. Elle travaille actuellement sur les différentes modalités dexposition de cette recherche qui seront présentées à partir de 2026.</p>
<h1>Virginie Bobin</h1>
<p>Virginie Bobin travaille de manière indépendante et souvent collective au croisement des pratiques curatoriales et éditoriales, de l'écriture, de la pédagogie et de la traduction. Après avoir œuvré pendant près de dix ans au sein de centres d'art et lieux de résidence en France et à l'international (Bétonsalon - Centre d'art et de recherche, la Villa Vassilieff, le Witte de With, Les Laboratoires d'Aubervilliers, Performa), elle s'efforce aujourd'hui d'instaurer des pratiques collectives d'apprentissage, d'écoute et de soin dans différents contextes, en s'appuyant sur des méthodologies féministes.<br>
En 2024, elle rejoint l'ésadhar de Rouen en tant que Professeure en Art et Pratiques sociales. Docteure en recherche artistique (PhD-in-Practice de lAcadémie des Beaux-Arts de Vienne, 2023), elle est membre co-fondatrice de la plateforme Qalqalah قلقلة (<a href="http://www.qalqalah.org">www.qalqalah.org</a>), avec laquelle elle a mené des projets à la Ferme du Buisson, au CRAC-Occitanie à Sète, à La Kunsthalle Mulhouse, au Tanzquartier (Vienne), à Buda (Courtrai), la Fondazione Pistoletto (Biella), l'Atelier de l'Observatoire (Casablanca) ou encore au Master exerce à l'ICI-CCN (Montpellier). Traductrice, elle collabore notamment avec le magazine The Funambulist.<br>
Ses projets curatoriaux et de recherche ont été présentés dans des institutions françaises et internationales telles que le CAC Brétigny, Bétonsalon - Centre d'art et de recherche, Museion (Bolzano), CentroCentro (Madrid), MoMA PS1 et e-flux space (New York) ou Tabakalera (San Sebastian). Elle a dirigé plusieurs ouvrages collectifs : Bestiario de Lengüitas (fruit d'une collaboration au long cours avec l'artiste Mercedes Azpilicueta, k.verlag, 2024), Composing Differences (Les Presses du Réel, 2015) et Re-publications (en collaboration avec Mathilde Villeneuve, Archive Books, 2015). Sont parus en 2025 : Désapprendre en traduisant : une pratique critique et collective (Villa Arson / Sternberg Press) et L'interprète dis/paraît (Scriptings).<br>
Vivant dans une commune rurale de Normandie, Virginie Bobin est membre des conseils d'administration du réseau RN13BIS et de l'association Kit de Survie.</p>
<h1>Fago</h1>
<p><strong>Ecouter</strong> des récits déracinés...<br>
<strong>Goûter</strong> une boisson d'accueil...<br>
<strong>Humer</strong> un paysage en mouvement...<br>
<strong>Toucher</strong> des gestes de réparation...<br>
<strong>Percevoir</strong> des jeux d'ombre et de lumière...</p>
</div>
<!-- END CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/field.html.twig' -->
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'field' -->
<!-- FILE NAME SUGGESTIONS:
▪️ field--node--field-partenaire-s--projet.html.twig
▪️ field--node--field-partenaire-s.html.twig
▪️ field--node--projet.html.twig
▪️ field--field-partenaire-s.html.twig
▪️ field--entity-reference.html.twig
✅ field.html.twig
-->
<!-- 💡 BEGIN CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/field.html.twig' -->
<div class="field_partenaire_s">
<div class="field-label">Partenaire(s) Associé(s)</div>
<div class="field-items multiple">
<div class="field-item"><a href="/node/57" hreflang="fr">Normandie Impressionniste</a></div>
</div>
</div>
<!-- END CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/field.html.twig' -->
</div>
<div class="col right">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'field' -->
<!-- FILE NAME SUGGESTIONS:
▪️ field--node--field-images--projet.html.twig
▪️ field--node--field-images.html.twig
▪️ field--node--projet.html.twig
▪️ field--field-images.html.twig
▪️ field--image.html.twig
✅ field.html.twig
-->
<!-- 💡 BEGIN CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/field.html.twig' -->
<div class="field_images field-items multiple">
<div class="field-item">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image_formatter' -->
<!-- BEGIN OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image' -->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<img loading="lazy" src="/sites/default/files/projets/103/103_IMG917.jpg" width="1920" height="1419" alt="Fago, Géraldine Longueville, 2026, sculpture en bambou, organza,treuil mécanique, corse, plantes. Crédits photographiques : © Marc Domage" />
<!-- END OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<!-- END OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
</div>
<div class="field-item">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image_formatter' -->
<!-- BEGIN OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image' -->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<img loading="lazy" src="/sites/default/files/projets/103/103_IMG1715.jpg" width="1920" height="1280" alt="Sharab, Géraldine Longueville, 2026, installation, mobilier, boisson d&#039;accueil, céramiques de Nina Safaïnia, bouteilles en grès, cuir. Crédits photographiques : © Marc Domage" />
<!-- END OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<!-- END OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
</div>
<div class="field-item">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image_formatter' -->
<!-- BEGIN OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image' -->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<img loading="lazy" src="/sites/default/files/projets/103/103_IMG1729.jpg" width="1280" height="1920" alt="Sharab, Géraldine Longueville, 2026, installation, mobilier, boisson d&#039;accueil, céramiques de Nina Safaïnia, bouteilles en grès, cuir. Performance de service réalisée par Morane Remaud. Crédits photographiques : © Marc Domage" />
<!-- END OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<!-- END OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
</div>
<div class="field-item">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image_formatter' -->
<!-- BEGIN OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image' -->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<img loading="lazy" src="/sites/default/files/projets/103/103_IMG2010.jpg" width="1920" height="1221" alt="Fago, Géraldine Longueville, 2026, sculpture en bambou, organza, treuil mécanique, corde, plantes. Crédits photographiques : © Marc Domage" />
<!-- END OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<!-- END OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
</div>
<div class="field-item">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image_formatter' -->
<!-- BEGIN OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image' -->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<img loading="lazy" src="/sites/default/files/projets/103/103_IMG2025.jpg" width="1920" height="1280" alt="Fago, Géraldine Longueville, 2026, sculpture en bambou, organza, treuil mécanique, corde, plantes. Crédits photographiques : © Marc Domage" />
<!-- END OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<!-- END OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
</div>
<div class="field-item">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image_formatter' -->
<!-- BEGIN OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image' -->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<img loading="lazy" src="/sites/default/files/projets/103/103_IMG2051.jpg" width="1920" height="1280" alt="Fago, Géraldine Longueville, 2026, sculpture en bambou, organza, treuil mécanique, corde, plantes. Crédits photographiques : © Marc Domage" />
<!-- END OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<!-- END OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
</div>
<div class="field-item">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image_formatter' -->
<!-- BEGIN OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image' -->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<img loading="lazy" src="/sites/default/files/projets/103/103_IMG2064.jpg" width="1920" height="1391" alt="Vous la rappelez-vous ?, Géraldine Longueville, 2026, installation en bambou, numérisation de cartes postales imprimées sur papier, aquarelle. Crédits photographiques : © Marc Domage" />
<!-- END OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<!-- END OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
</div>
<div class="field-item">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image_formatter' -->
<!-- BEGIN OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image' -->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<img loading="lazy" src="/sites/default/files/projets/103/103_IMG2070.jpg" width="1920" height="1280" alt="kinakina, Géraldine Longueville, 2024, vidéo (durée : 25min), images, composition, voix : Géraldine Longueville ; Darbouka ; Olivier Longueville ; Dobro : John Molan et Elie Godard ; Arrangement sonore et mixage : Thomas Schmahl. Crédits photographiques : © Marc Domage" />
<!-- END OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<!-- END OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
</div>
<div class="field-item">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image_formatter' -->
<!-- BEGIN OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image' -->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<img loading="lazy" src="/sites/default/files/projets/103/103_IMG2075.jpg" width="1280" height="1920" alt="Fuma, Géraldine Longueville, 2026, performance et sculpture de plantes consumées, collier à vis. Crédits photographiques : © Marc Domage" />
<!-- END OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<!-- END OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
</div>
<div class="field-item">
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image_formatter' -->
<!-- BEGIN OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'image' -->
<!-- BEGIN OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<img loading="lazy" src="/sites/default/files/projets/103/103_IMG2088.jpg" width="1920" height="1280" alt="Vous la rappelez-vous ?, Géraldine Longueville, 2026, installation en bambou, numérisation de cartes postales imprimées sur papier, aquarelle. Crédits photographiques : © Marc Domage" />
<!-- END OUTPUT from 'core/modules/system/templates/image.html.twig' -->
<!-- END OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
</div>
</div>
<!-- END CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/field.html.twig' -->
</div>
</div>
</article>
<!-- END CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/node--projet--full.html.twig' -->
</div>
<!-- END CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/region.html.twig' -->
</div>
</main>
</div>
<!-- END CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/page.html.twig' -->
</div>
<!-- END OUTPUT from 'core/modules/system/templates/off-canvas-page-wrapper.html.twig' -->
<script type="application/json" data-drupal-selector="drupal-settings-json">{"path":{"baseUrl":"\/","pathPrefix":"","currentPath":"node\/570","currentPathIsAdmin":false,"isFront":false,"currentLanguage":"fr"},"pluralDelimiter":"\u0003","suppressDeprecationErrors":true,"data":{"extlink":{"extTarget":false,"extTargetAppendNewWindowDisplay":false,"extTargetAppendNewWindowLabel":"(opens in a new window)","extTargetNoOverride":false,"extNofollow":false,"extTitleNoOverride":false,"extNoreferrer":false,"extFollowNoOverride":false,"extClass":"ext","extLabel":"(le lien est externe)","extImgClass":false,"extSubdomains":true,"extExclude":"","extInclude":"","extCssExclude":"","extCssInclude":"","extCssExplicit":"","extAlert":false,"extAlertText":"Ce lien vous dirige vers un site externe. Nous ne sommes pas responsables de son contenu.","extHideIcons":false,"mailtoClass":"mailto","telClass":"tel","mailtoLabel":"(link sends email)","telLabel":"(link is a phone number)","extUseFontAwesome":false,"extIconPlacement":"append","extPreventOrphan":false,"extFaLinkClasses":"fa fa-external-link","extFaMailtoClasses":"fa fa-envelope-o","extAdditionalLinkClasses":"","extAdditionalMailtoClasses":"","extAdditionalTelClasses":"","extFaTelClasses":"fa fa-phone","allowedDomains":null,"extExcludeNoreferrer":""}},"user":{"uid":0,"permissionsHash":"ec925e94d2171db34f4a2e24795940b32ebbfae3c8882b3c70d7f1931d114517"}}</script>
<script src="/sites/default/files/languages/fr_CrdT4JHfBTSbUhzO9RLz5imL3dFblqGqJOpzKqtwZGA.js?tjtjpd"></script>
<script src="/core/misc/drupalSettingsLoader.js?v=10.6.10"></script>
<script src="/core/misc/drupal.js?v=10.6.10"></script>
<script src="/core/misc/drupal.init.js?v=10.6.10"></script>
<script src="/modules/contrib/extlink/js/extlink.js?tjtjpd"></script>
<script src="http://localhost:5173/@vite/client" type="module"></script>
<script src="http://localhost:5173/assets/js/main.js" type="module"></script>
</body>
</html>
<!-- END CUSTOM TEMPLATE OUTPUT from 'themes/custom/leshed/templates/html.html.twig' -->
+29
View File
@@ -0,0 +1,29 @@
uuid: 013d1fb2-1c81-4b8b-93ca-0da2e401fd88
langcode: fr
status: false
dependencies:
module:
- ctools_block
theme:
- leshed
id: leshed_titre
theme: leshed
region: content
weight: 0
provider: null
plugin: 'entity_field:node:title'
settings:
id: 'entity_field:node:title'
label: Titre
label_display: '0'
provider: ctools_block
context_mapping:
entity: '@node.node_route_context:node'
formatter:
type: string
weight: 0
label: above
settings:
link_to_entity: false
third_party_settings: { }
visibility: { }
+8
View File
@@ -0,0 +1,8 @@
uuid: 177f93c8-cb82-4d48-a9f0-ba1f88df350b
langcode: fr
status: true
dependencies: { }
id: d_m_y
label: 'd M Y'
locked: false
pattern: 'd M Y'
@@ -31,7 +31,7 @@ content:
label: hidden
settings: { }
third_party_settings: { }
weight: 101
weight: 1
region: content
field_artiste_s_invite_s:
type: entity_reference_label
@@ -39,18 +39,18 @@ content:
settings:
link: true
third_party_settings: { }
weight: 105
weight: 6
region: content
field_dates:
type: daterange_default
label: above
label: visually_hidden
settings:
timezone_override: ''
format_type: medium
from_to: both
separator: '-'
third_party_settings: { }
weight: 102
weight: 2
region: content
field_fichiers:
type: file_default
@@ -58,7 +58,7 @@ content:
settings:
use_description_as_link_text: true
third_party_settings: { }
weight: 110
weight: 9
region: content
field_images:
type: image
@@ -69,7 +69,7 @@ content:
image_loading:
attribute: lazy
third_party_settings: { }
weight: 109
weight: 10
region: content
field_invite_accompagne_curate_p:
type: entity_reference_label
@@ -77,7 +77,7 @@ content:
settings:
link: true
third_party_settings: { }
weight: 106
weight: 4
region: content
field_partenaire_s:
type: entity_reference_label
@@ -85,14 +85,14 @@ content:
settings:
link: true
third_party_settings: { }
weight: 104
weight: 5
region: content
field_portage:
type: list_default
label: above
settings: { }
third_party_settings: { }
weight: 107
weight: 7
region: content
field_projet_s_lie_s:
type: entity_reference_label
@@ -100,20 +100,20 @@ content:
settings:
link: true
third_party_settings: { }
weight: 108
weight: 8
region: content
field_type_de_projet:
type: entity_reference_label
label: above
label: visually_hidden
settings:
link: true
third_party_settings: { }
weight: 103
weight: 3
region: content
links:
settings: { }
third_party_settings: { }
weight: 100
weight: 0
region: content
hidden:
langcode: true
@@ -0,0 +1,116 @@
uuid: 3e27c55e-5165-4118-bd03-5c0433642e42
langcode: fr
status: true
dependencies:
config:
- core.entity_view_mode.node.full
- field.field.node.projet.body
- field.field.node.projet.field_artiste_s_invite_s
- field.field.node.projet.field_dates
- field.field.node.projet.field_fichiers
- field.field.node.projet.field_images
- field.field.node.projet.field_invite_accompagne_curate_p
- field.field.node.projet.field_partenaire_s
- field.field.node.projet.field_portage
- field.field.node.projet.field_projet_s_lie_s
- field.field.node.projet.field_type_de_projet
- image.style.large
- node.type.projet
module:
- datetime_range
- file
- image_field_caption
- layout_builder
- options
- text
- user
third_party_settings:
layout_builder:
enabled: false
allow_custom: false
id: node.projet.full
targetEntityType: node
bundle: projet
mode: full
content:
body:
type: text_default
label: hidden
settings: { }
third_party_settings: { }
weight: 3
region: content
field_artiste_s_invite_s:
type: entity_reference_label
label: hidden
settings:
link: true
third_party_settings: { }
weight: 0
region: content
field_dates:
type: daterange_default
label: hidden
settings:
timezone_override: ''
format_type: d_m_y
from_to: both
separator: '-'
third_party_settings: { }
weight: 2
region: content
field_fichiers:
type: file_default
label: above
settings:
use_description_as_link_text: true
third_party_settings: { }
weight: 7
region: content
field_images:
type: image_caption
label: hidden
settings:
image_style: large
image_link: file
image_loading:
attribute: lazy
third_party_settings: { }
weight: 8
region: content
field_invite_accompagne_curate_p:
type: entity_reference_label
label: above
settings:
link: true
third_party_settings: { }
weight: 1
region: content
field_partenaire_s:
type: entity_reference_label
label: above
settings:
link: true
third_party_settings: { }
weight: 4
region: content
field_portage:
type: list_default
label: above
settings: { }
third_party_settings: { }
weight: 5
region: content
field_projet_s_lie_s:
type: entity_reference_label
label: above
settings:
link: true
third_party_settings: { }
weight: 6
region: content
hidden:
field_type_de_projet: true
langcode: true
links: true
search_api_excerpt: true
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+174 -3
View File
@@ -4,6 +4,13 @@ import '../scss/main.scss'
import "splitting/dist/splitting.css";
import "splitting/dist/splitting-cells.css";
import Splitting from "splitting";
import { hyphenateSync } from "hyphen/fr";
import { gsap, Power1 } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import Lenis from 'lenis';
import 'fslightbox';
gsap.registerPlugin(ScrollTrigger);
// import Content from './vuejs/Content.vue'
@@ -34,15 +41,22 @@ import Splitting from "splitting";
const _is_front = drupalSettings.path.isFront
console.log('drupalSettings', drupalSettings)
const scroller = document.querySelector('main[role="main"]');
const gsap_mm = gsap.matchMedia();
console.log('gsap_mm', gsap_mm);
// ___ _ _
// |_ _|_ _ (_) |_
// | || ' \| | _|
// |___|_||_|_|\__|
function init () {
console.log('LeShedTheme init()')
console.log('LeShedTheme init()');
initTitles();
initBurgerMenu();
initSmoothScroll();
initColumnScrollSync();
initFsLightbox();
// initVues()
}
@@ -75,13 +89,54 @@ import Splitting from "splitting";
};
function initTitles() {
const titles = document.querySelectorAll('#block-leshed-identitedusite>a, article.node-type-projet>header>h2');
const titles = document.querySelectorAll('#block-leshed-identitedusite>a, article.node-type-projet>header>h2, article.node-type-projet>.cols>.left>h2');
for (const txt of titles) {
txt.classList.add("variable-title");
const splitted = Splitting({ target: txt, by: 'chars' });
for (const word of splitted[0].words) {
styleWordChars(Array.from(word.getElementsByClassName('char')));
const chars = Array.from(word.getElementsByClassName('char'));
styleWordChars(chars);
hyphenateWord(chars);
}
}
const pageTitle = document.querySelector('article.node-type-projet.view-mode-full h2.node-title');
console.log('pageTitle', pageTitle);
if (pageTitle) {
// needs requestAnimationFrame to get the real titleHeight after splitting
requestAnimationFrame(() => {
requestAnimationFrame(() => {
const initTitleH = pageTitle.offsetHeight;
// console.log(`initTitleH: ${initTitleH}`);
const titleScaleTarget = 0.4;
const end = initTitleH - initTitleH * titleScaleTarget;
// console.log(`end: ${end}`);
gsap_mm.add('(min-width: 768px)', () => {
gsap.to(pageTitle, {
scale: titleScaleTarget,
y: end,
ease: 'none',
scrollTrigger: {
scroller: scroller,
start: 0,
end: end, // scroll maximum du conteneur (robuste au resize)
scrub: true,
invalidateOnRefresh: true,
},
});
})
});
});
}
}
/**
@@ -175,6 +230,37 @@ import Splitting from "splitting";
}
}
/**
* Insère des césures logicielles (U+00AD) aux points de coupure valides.
*
* Comme chaque lettre est un span (display:inline) sans « run » de texte
* continu, `hyphens: auto` est inopérant : on calcule donc les points de
* césure (motifs FR) et on insère un soft hyphen — en nœud texte, entre les
* lettres concernées — qui n'autorise une coupure (avec tiret) qu'à ces
* endroits. Les mots trop longs coupent proprement au lieu de casser
* n'importe où.
*/
function hyphenateWord(chars) {
if (chars.length < 5) return;
const SOFT = '\u00AD';
const text = chars.map((c) => c.textContent).join('');
const hyphenated = hyphenateSync(text);
if (!hyphenated.includes(SOFT)) return;
let letter = 0;
for (const ch of hyphenated) {
if (ch === SOFT) {
const target = chars[letter];
if (letter > 0 && target && target.parentNode) {
target.parentNode.insertBefore(document.createTextNode(SOFT), target);
}
}
else {
letter++;
}
}
}
function initBurgerMenu() {
let header_right = document.getElementById('burger-btn');
header_right.parentElement.addEventListener('click', function(e){
@@ -184,6 +270,91 @@ import Splitting from "splitting";
})
}
/**
* Scroll lissé (Lenis) sur le conteneur `main` — et non la fenêtre, car
* c'est `main[role="main"]` qui porte l'overflow. Lenis est branché sur le
* ticker GSAP (une seule boucle RAF) et pousse ses updates à ScrollTrigger
* pour que la synchro des colonnes reste calée sur le scroll lissé.
*/
function initSmoothScroll() {
const scroller = document.querySelector('main[role="main"]');
const content = scroller && scroller.querySelector('.layout-content');
if (!scroller || !content) return;
const lenis = new Lenis({
wrapper: scroller, // conteneur scrollable custom
content: content, // contenu réel (le 1er enfant est l'ancre skip-link)
duration: 1.2,
smoothWheel: true,
});
lenis.on('scroll', ScrollTrigger.update);
gsap.ticker.add((time) => lenis.raf(time * 1000));
gsap.ticker.lagSmoothing(0);
}
/**
* Synchronise le scroll des deux colonnes du layout 50/50 : la colonne la
* plus courte est ralentie (translateY décroissant) pour que son bas soit
* atteint en même temps que celui de la colonne la plus haute, qui défile
* nativement (flux normal, pas de pin). Le scroll réel a lieu dans
* `main[role="main"]`, pas dans la fenêtre : GSAP utilise donc ce conteneur
* comme `scroller`.
*/
function initColumnScrollSync() {
console.log('initColumnScrollSync');
const firstColumn = document.querySelector('.layout--twocol-section--50-50 .layout__region--first');
const secondColumn = document.querySelector('.layout--twocol-section--50-50 .layout__region--second');
console.log(scroller, firstColumn, secondColumn);
if (!scroller || !firstColumn || !secondColumn) return;
gsap_mm.add('(min-width: 768px)', () => {
[firstColumn, secondColumn].forEach((column) => {
gsap.to(column, {
// Distance à parcourir pour que le bas de la colonne arrive en
// bas du viewport en même temps que la colonne la plus haute.
y: () => {
const visibleHeight = scroller.clientHeight;
const scrollRange = scroller.scrollHeight - scroller.clientHeight;
const columnRevealRange = Math.max(0, column.offsetHeight - visibleHeight);
return scrollRange - columnRevealRange;
},
ease: 'none',
scrollTrigger: {
scroller: scroller,
start: 0,
end: 'max', // scroll maximum du conteneur (robuste au resize)
// Valeur numérique = easing : l'animation met ~0.6s à rattraper la
// position de scroll au lieu de la suivre au pixel près → lisse les
// à-coups de la colonne lente. Monter la valeur = plus d'inertie.
scrub: true,
invalidateOnRefresh: true,
},
});
});
// Nettoyage automatique des tweens/triggers quand on repasse sous 768px.
return () => {};
});
// Les images chargent après coup et changent la hauteur des colonnes.
window.addEventListener('load', () => ScrollTrigger.refresh());
}
function initFsLightbox(){
console.log('initFsLightbox');
// console.log(window.FsLightbox);
let imgs_links = document.querySelectorAll('article.node-type-projet.view-mode-full .field_images.multiple .field-item a');
for (const link of imgs_links) {
link.setAttribute("data-fslightbox", "gallery")
}
// window.FsLightbox
window.refreshFsLightbox();
}
// function initVues(){
// console.log('initVues');
+170 -24
View File
@@ -1,3 +1,4 @@
@import "partials/variables";
@import "partials/colors";
@import "partials/fonts";
@import "partials/mixins";
@@ -11,9 +12,22 @@ a, a:visited{
body{
margin: 0;
// background-color: green;
font-weight: $default_fwght;
line-height: 1.5;
}
// Splitting met .word ET .char en inline-block :
// - inline-block sur .char crée une opportunité de coupure entre CHAQUE lettre ;
// - inline-block sur .word (dimensionné en max-content) empêche tout retour à la
// ligne interne, donc les soft hyphens ne peuvent jamais couper le mot.
// On repasse les deux en inline : le mot redevient un flux de texte qui ne coupe
// qu'aux césures logicielles (U+00AD) insérées par le JS.
// Spécificité (0,2,1) pour battre `.splitting .word/.char` de Splitting.
.splitting span.word,
.splitting span.char{
display: inline;
}
$header_height: 50px;
// _ _
// | | | |
@@ -32,13 +46,16 @@ div.layout-container{
max-width:1080px;
margin: 0 auto;
header[role="banner"]{
display: block;
position: relative;
padding: 0.5em 0;
flex: 0 1 content;
flex: 1 1 $header_height;
z-index: 100;
// position: fixed;
// top:0;
// width: 100%;
height: $header_height;
min-height: $header_height;
}
main[role="main"]{
flex: 1 1 auto;
@@ -81,7 +98,7 @@ header[role="banner"]{
text-decoration: none;
font-size: 2em;
font-weight: 500;
margin-right: 0.5em;
// &:hover{
// color: $rose;
// }
@@ -102,7 +119,7 @@ header[role="banner"]{
&, &::before, &::after{
// position: absolute;
width:20px; height:3px;
background-color: red;
background-color: #000;
}
&:hover{
@@ -171,6 +188,23 @@ header[role="banner"]{
} // end of header[role="banner"]{
.variable-title{
margin: 0;
font-weight: 200;
text-transform:lowercase;
line-height: 1;
// margin-left: -0.04em;
filter: drop-shadow(0 0 5px #fff) drop-shadow(0 0 15px #fff);
span.word{
span.char{
letter-spacing:-0.1em;
}
}
// span.whitespace{
// letter-spacing: 0.5em;
// }
}
// _____ _____ __ ____ ___ _ ____
// |_ _/ _ \ \ / / / ___/ _ \| | / ___|
// | || | | \ \ /\ / / | | | | | | | \___ \
@@ -179,34 +213,24 @@ header[role="banner"]{
div.layout.layout--twocol-section--50-50{
flex-wrap: nowrap;
column-gap: 1em;
// Sans ça, `align-items: stretch` (défaut flex) étire les deux colonnes à la
// même hauteur : la synchro de scroll ne verrait aucune différence de hauteur.
// flex-start = chaque colonne prend la hauteur de son contenu.
align-items: flex-start;
column-gap: $colsgap;
div.layout__region{
max-width: calc(50% - $colsgap / 2);
flex: 1 0 calc(50% - $colsgap / 2);
.views-row{
// border: 1px solid red;
// box-sizing: border-box;
margin-bottom: 1.5em;
margin-bottom: 2em;
max-width: 100%;
article.node-type-projet{
>header{
>h2{
margin: 0;
font-size: 5em;
text-transform:lowercase;
filter: drop-shadow(0 0 5px #fff) drop-shadow(0 0 15px #fff);
span.word{
hyphens: auto;
// $bgcolor:rgba(255,255,255,0.8);
// // background-color: $bgcolor;
// border-radius: 0.8em;
// box-shadow: 0 0 20px #fff;
span.char{
letter-spacing:-0.2em;
}
}
// span.whitespace{
// letter-spacing: 0.5em;
// }
}
}
>div{
@@ -243,3 +267,125 @@ div.layout.layout--twocol-section--50-50{
}
}
}
// ____ _ _
// | _ \ _ __ ___ (_) ___| |_
// | |_) | '__/ _ \| |/ _ \ __|
// | __/| | | (_) | | __/ |_
// |_| |_| \___// |\___|\__|
// |__/
article.node-type-projet.view-mode-full{
div.cols{
display: flex;
flex-direction: row;
gap: $colsgap;
// column-gap: 2em;
div.col{
flex:0 0 calc(50% - $colsgap / 2);
max-width: calc(50% - $colsgap / 2);
&.left{
>h2.node-title{
position: relative;
font-size: 12em;
margin: 0;
z-index: 100;
width: 205%;//calc(50% - $colsgap / 2);
pointer-events: none;
transform-origin: 0 0;
}
.field_artiste_s_invite_s{
font-size: 1.8em;
font-weight: 300;
}
.field_invite_accompagne_curate_p{
font-weight: 400;
.field-label{
font-weight: $default_fwght;
}
>div{
display: inline-block;
}
}
.field_dates{
time{
font-weight: 400;
}
}
}
&.right{
// Étire .field_images sur toute la hauteur de la colonne (= colonne la
// plus haute, via le stretch de .cols) : le contexte de collage sticky
// couvre alors tout le scroll, donc les cartes restent figées tant que
// la colonne gauche défile encore (cf. point 6).
display: flex;
.field_images{
flex: 1;
// .field-items{
&:after{
display: block;
position: relative;
content: "";
// border: 1px solid red;
width: 100%;
height: 100vh;
}
// }
.field-item{
position: relative;
// Empilement "cartes" : chaque image se fige au même endroit (haut) et
// est recouverte par la suivante (l'ordre du DOM fait que la dernière
// passe au-dessus). La 1re image ne bouge pas. Desktop uniquement.
@media (min-width: 768px){
position: sticky;
top: 0;
// &:last-child:after{
// content: "";
// // position: relative;
// display:block;
// // blockquote.image-field-caption{
// height: 100vh;
// width:100%;
// border: 1px solid red;
// // }
// }
}
img{
width: 100%;
max-width: 100%;
height: auto;
}
blockquote.image-field-caption{
margin: 0;
position: absolute;
bottom: 0; left: 0;
width: 100%;
background-color: rgba(0,0,0,0.65);
color: #fff;
p{
margin: 0;
padding: 1em;
font-weight: 300;
font-size: 0.8em;
}
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
&:hover{
z-index:200;
blockquote.image-field-caption{
opacity: 1;
}
}
}
}
}
}
}
}
@@ -0,0 +1,3 @@
$default_fwght: 200;
$header_height: 70px;
$colsgap: 2em;
+2
View File
@@ -82,6 +82,8 @@ function leshed_preprocess_node(&$variables) {
}
$variables["attributes"]['class'][] = "node-type-{$node_type}";
$variables["attributes"]['class'][] = "view-mode-{$variables['view_mode']}";
if ($variables['view_mode'] === "teaser") {
/** @var \Drupal\file\Plugin\\Field\FieldType\FileFieldItemList $field_images */
$field_images = $node->get('field_images');
+46
View File
@@ -9,7 +9,10 @@
"version": "0.0.0",
"dependencies": {
"axios": "^1.7.2",
"fslightbox": "^3.7.5",
"gsap": "^3.14.1",
"hyphen": "^1.14.1",
"lenis": "^1.3.26",
"splitting": "^1.1.0",
"vue": "^3.4.29"
},
@@ -1581,6 +1584,12 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/fslightbox": {
"version": "3.7.5",
"resolved": "https://registry.npmjs.org/fslightbox/-/fslightbox-3.7.5.tgz",
"integrity": "sha512-swEUrwMOyiBhdkPf3GXj4nxARX5d8/9yfVCdxgPLl9+ZMiacUTub9O2wxLI0Y2G2jI85Qxfqpv2I24vlbx0zfg==",
"license": "MIT"
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -1697,6 +1706,12 @@
"node": ">= 6"
}
},
"node_modules/hyphen": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/hyphen/-/hyphen-1.14.1.tgz",
"integrity": "sha512-kvL8xYl5QMTh+LwohVN72ciOxC0OEV79IPdJSTwEXok9y9QHebXGdFgrED4sWfiax/ODx++CAMk3hMy4XPJPOw==",
"license": "ISC"
},
"node_modules/immutable": {
"version": "5.1.9",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz",
@@ -1729,6 +1744,37 @@
"node": ">=0.10.0"
}
},
"node_modules/lenis": {
"version": "1.3.26",
"resolved": "https://registry.npmjs.org/lenis/-/lenis-1.3.26.tgz",
"integrity": "sha512-s/xTCZCxTFvHbAN1OzuhNaN5YPJH2ail0XAkctKW1b+RUAG4nUL5UHLXwNko1h8aEeT2jspBXegMgPJd8zcuag==",
"license": "MIT",
"workspaces": [
"packages/*",
"playground",
"playground/*"
],
"funding": {
"type": "github",
"url": "https://github.com/sponsors/darkroomengineering"
},
"peerDependencies": {
"@nuxt/kit": ">=3.0.0",
"react": ">=17.0.0",
"vue": ">=3.0.0"
},
"peerDependenciesMeta": {
"@nuxt/kit": {
"optional": true
},
"react": {
"optional": true
},
"vue": {
"optional": true
}
}
},
"node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+3
View File
@@ -10,7 +10,10 @@
},
"dependencies": {
"axios": "^1.7.2",
"fslightbox": "^3.7.5",
"gsap": "^3.14.1",
"hyphen": "^1.14.1",
"lenis": "^1.3.26",
"splitting": "^1.1.0",
"vue": "^3.4.29"
},
@@ -0,0 +1,72 @@
{#
/**
* @file
* Default theme implementation for a field.
*
* To override output, copy the "field.html.twig" from the templates directory
* to your theme's directory and customize it, just like customizing other
* Drupal templates such as page.html.twig or node.html.twig.
*
* Instead of overriding the theming for all fields, you can also just override
* theming for a subset of fields using
* @link themeable Theme hook suggestions. @endlink For example,
* here are some theme hook suggestions that can be used for a field_foo field
* on an article node type:
* - field--node--field-foo--article.html.twig
* - field--node--field-foo.html.twig
* - field--node--article.html.twig
* - field--field-foo.html.twig
* - field--text-with-summary.html.twig
* - field.html.twig
*
* Available variables:
* - attributes: HTML attributes for the containing element.
* - label_hidden: Whether to show the field label or not.
* - title_attributes: HTML attributes for the title.
* - label: The label for the field.
* - multiple: TRUE if a field can contain multiple items.
* - items: List of all the field items. Each item contains:
* - attributes: List of HTML attributes for each item.
* - content: The field item's content.
* - entity_type: The entity type to which the field belongs.
* - field_name: The name of the field.
* - field_type: The type of the field.
* - label_display: The display settings for the label.
*
* @see template_preprocess_field()
*
* @ingroup themeable
*/
#}
{%
set title_classes = [
label_display == 'visually_hidden' ? 'visually-hidden',
]
%}
{% if label_hidden %}
{% if multiple %}
<div{{ attributes.addClass("field-items").addClass("multiple") }}>
{% for item in items %}
<div{{ item.attributes.addClass("field-item") }}>{{ item.content }}</div>
{% endfor %}
</div>
{% else %}
{% for item in items %}
<div{{ attributes.addClass("field-item") }}>{{ item.content }}</div>
{% endfor %}
{% endif %}
{% else %}
<div{{ attributes }}>
<div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div>
{% if multiple %}
<div class="field-items multiple">
{% endif %}
{% for item in items %}
<div{{ item.attributes.addClass("field-item") }}>{{ item.content }}</div>
{% endfor %}
{% if multiple %}
</div>
{% endif %}
</div>
{% endif %}
@@ -0,0 +1,79 @@
{#
/**
* @file
* Default theme implementation to display a node.
*
* Available variables:
* - node: The node entity with limited access to object properties and methods.
* Only method names starting with "get", "has", or "is" and a few common
* methods such as "id", "label", and "bundle" are available. For example:
* - node.getCreatedTime() will return the node creation timestamp.
* - node.hasField('field_example') returns TRUE if the node bundle includes
* field_example. (This does not indicate the presence of a value in this
* field.)
* - node.isPublished() will return whether the node is published or not.
* Calling other methods, such as node.delete(), will result in an exception.
* See \Drupal\node\Entity\Node for a full list of public properties and
* methods for the node object.
* - label: (optional) The title of the node.
* - content: All node items. Use {{ content }} to print them all,
* or print a subset such as {{ content.field_example }}. Use
* {{ content|without('field_example') }} to temporarily suppress the printing
* of a given child element.
* - author_picture: The node author user entity, rendered using the "compact"
* view mode.
* - metadata: Metadata for this node.
* - date: (optional) Themed creation date field.
* - author_name: (optional) Themed author name field.
* - url: Direct URL of the current node.
* - display_submitted: Whether submission information should be displayed.
* - attributes: HTML attributes for the containing element.
* The attributes.class element may contain one or more of the following
* classes:
* - node: The current template type (also known as a "theming hook").
* - node--type-[type]: The current node type. For example, if the node is an
* "Article" it would result in "node--type-article". Note that the machine
* name will often be in a short form of the human readable label.
* - node--view-mode-[view_mode]: The View Mode of the node; for example, a
* teaser would result in: "node--view-mode-teaser", and
* full: "node--view-mode-full".
* The following are controlled through the node publishing options.
* - node--promoted: Appears on nodes promoted to the front page.
* - node--sticky: Appears on nodes ordered above other non-sticky nodes in
* teaser listings.
* - node--unpublished: Appears on unpublished nodes visible only to site
* admins.
* - title_attributes: Same as attributes, except applied to the main title
* tag that appears in the template.
* - content_attributes: Same as attributes, except applied to the main
* content tag that appears in the template.
* - author_attributes: Same as attributes, except applied to the author of
* the node tag that appears in the template.
* - title_prefix: Additional output populated by modules, intended to be
* displayed in front of the main title tag that appears in the template.
* - title_suffix: Additional output populated by modules, intended to be
* displayed after the main title tag that appears in the template.
* - view_mode: View mode; for example, "teaser" or "full".
* - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'.
* - page: Flag for the full page state. Will be true if view_mode is 'full'.
*
* @see template_preprocess_node()
*
* @ingroup themeable
*/
#}
<article{{ attributes }}>
<div class="cols">
<div class="col left">
<h2{{ title_attributes.addClass('node-title') }}>
{{ label }}
</h2>
{{ content|without('field_images') }}
</div>
<div class="col right">
{{ content.field_images }}
</div>
</div>
</article>
@@ -65,9 +65,13 @@
<article{{ attributes }}>
{{ title_prefix }}
{% if label and not page %}
{% if label %}
<h2{{ title_attributes }}>
<a href="{{ url }}" rel="bookmark">{{ label }}</a>
{% if not page %}
<a href="{{ url }}" rel="bookmark">{{ label }}</a>
{% else %}
{{ label }}
{% endif %}
</h2>
{% endif %}
{{ title_suffix }}