design bottom bar
All checks were successful
Deploy / Deploy to Production (push) Successful in 13s

This commit is contained in:
Julie Blanc 2026-02-20 14:09:25 +01:00
parent f1ace8cc05
commit a1eda42d87
13 changed files with 288 additions and 221 deletions

View file

@ -118,6 +118,21 @@ body, #site-header, #site-footer{
}
@mixin icon($size){
.icon{
display: flex;
width: $size;
height: $size;
svg{
width: $size;
height: $size;
}
}
}
body.menu-open,
body.is-hidden{

View file

@ -0,0 +1,66 @@
.bottom-bar{
position: fixed;
bottom: 0;
left: 0;
height: calc(var(--header-h)*0.75);
width: 100vw;
background-color: var(--color-bg);
padding-left: var(--padding-body);
padding-right: var(--padding-body);
border-top: 2px solid var(--grey-800);
.bottom-bar__inner{
height: calc(var(--header-h)*0.75);
display: flex;
justify-content: flex-end;
align-items: center;
gap: var(--padding-inner);
}
.btn--back-to-top{
@include icon(20px);
position: relative;
top: -3px;
width: 100px;
a{
justify-content: flex-end;
}
.icon{
transform: rotate(-90deg);
transform-origin: center;
}
}
.title-group{
font-size: var(--fs-small);
display: flex;
color: var(--color-txt-light);
flex-grow: 1;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
// align-items: center;
.type{
text-transform: uppercase;
&::after{
content: "/";
padding-left: 1ch;
padding-right: 1ch;
}
}
}
}

View file

@ -92,6 +92,42 @@ button:disabled{
a{ color: var(--color-bg); }
svg{ fill: var(--color-bg); }
}
.btn--simple{
height: calc(var(--h-block)*1);
font-size: var(--fs-small);
font-weight: 500;
text-transform: uppercase;
line-height: 1;
white-space: nowrap;
@include icon(20px);
.icon{
position: relative;
top: -2px;
}
a{
display: flex;
align-items: center;
justify-content: center;
gap: 1ch;
width: 100%;
height: 100%;
padding: 0 2ch;
padding-top: 4px;
white-space: nowrap;
}
&.no-link{
display: flex;
align-items: center;
justify-content: center;
gap: 1ch;
padding: 0 2ch;
padding-top: 4px;
}
}
.btn--bold,
.btn--bold-inline{
@ -264,5 +300,11 @@ button:disabled{
}
.btn--support{
color: var(--color-accent);
&:hover{
color: var(--color-accent);
text-decoration: underline;
text-underline-offset: 2px;
}
}

View file

@ -344,6 +344,47 @@ button:disabled {
fill: var(--color-bg);
}
.btn--simple {
height: calc(var(--h-block) * 1);
font-size: var(--fs-small);
font-weight: 500;
text-transform: uppercase;
line-height: 1;
white-space: nowrap;
}
.btn--simple .icon {
display: flex;
width: 20px;
height: 20px;
}
.btn--simple .icon svg {
width: 20px;
height: 20px;
}
.btn--simple .icon {
position: relative;
top: -2px;
}
.btn--simple a {
display: flex;
align-items: center;
justify-content: center;
gap: 1ch;
width: 100%;
height: 100%;
padding: 0 2ch;
padding-top: 4px;
white-space: nowrap;
}
.btn--simple.no-link {
display: flex;
align-items: center;
justify-content: center;
gap: 1ch;
padding: 0 2ch;
padding-top: 4px;
}
.btn--bold,
.btn--bold-inline {
display: block;
@ -480,6 +521,15 @@ button:disabled {
fill: var(--grey-100);
}
.btn--support {
color: var(--color-accent);
}
.btn--support:hover {
color: var(--color-accent);
text-decoration: underline;
text-underline-offset: 2px;
}
.category {
height: calc(var(--h-block) * 0.75);
border-radius: var(--radius-small);
@ -1994,6 +2044,64 @@ button.sort[data-sort-type=up] .arrow {
box-shadow: 1px 1px 1px hsla(0, 50%, 2%, 0.5);
}
.bottom-bar {
position: fixed;
bottom: 0;
left: 0;
height: calc(var(--header-h) * 0.75);
width: 100vw;
background-color: var(--color-bg);
padding-left: var(--padding-body);
padding-right: var(--padding-body);
border-top: 2px solid var(--grey-800);
}
.bottom-bar .bottom-bar__inner {
height: calc(var(--header-h) * 0.75);
display: flex;
justify-content: flex-end;
align-items: center;
gap: var(--padding-inner);
}
.bottom-bar .btn--back-to-top .icon {
display: flex;
width: 20px;
height: 20px;
}
.bottom-bar .btn--back-to-top .icon svg {
width: 20px;
height: 20px;
}
.bottom-bar .btn--back-to-top {
position: relative;
top: -3px;
width: 100px;
}
.bottom-bar .btn--back-to-top a {
justify-content: flex-end;
}
.bottom-bar .btn--back-to-top .icon {
transform: rotate(-90deg);
transform-origin: center;
}
.bottom-bar .title-group {
font-size: var(--fs-small);
display: flex;
color: var(--color-txt-light);
flex-grow: 1;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.bottom-bar .title-group .type {
text-transform: uppercase;
}
.bottom-bar .title-group .type::after {
content: "/";
padding-left: 1ch;
padding-right: 1ch;
}
#site-header {
z-index: var(--z-header);
--gap: 3ch;

File diff suppressed because one or more lines are too long

View file

@ -29,6 +29,7 @@
@import "components/card-open-graph";
@import "components/swiper";
@import "components/slider-before-after";
@import "components/bottom-bar";
@import "partials/site-header";
@import "partials/site-menu";

View file

@ -1,58 +0,0 @@
let isInitialized = false;
export function bannerStickyDesktop(responsiveSmall) {
if (isInitialized) return;
let body = document.body;
let panel = body.querySelector(".panel-left");
if (!panel) return;
let footer = document.querySelector("#site-footer");
// Stocker la hauteur initiale du banner
const bannerInitialHeight = panel.offsetHeight;
function checkScroll() {
const screenWidth = window.innerWidth;
// Vérifier que l'écran est plus grand que responsiveSmall
if (screenWidth <= responsiveSmall) {
// Réinitialiser le transform si on est en dessous de responsiveSmall
panel.style.transform = '';
return;
}
// Calculer la position du bas de la fenêtre
const windowBottom = window.scrollY + window.innerHeight;
// Calculer dynamiquement la position du footer à chaque scroll
// Utiliser getBoundingClientRect() + scrollY pour une valeur toujours à jour
const footerTop = footer.getBoundingClientRect().top + window.scrollY;
// Calculer de combien on dépasse le haut du footer
const overlap = windowBottom - footerTop;
if (overlap > 0) {
// Le bas de la fenêtre a atteint le haut du footer
// Déplacer le banner vers le haut du nombre de pixels de dépassement
const translateValue = Math.min(overlap, bannerInitialHeight);
panel.style.transform = `translateY(-${translateValue}px)`;
} else {
// Réinitialiser la position si on n'a pas encore atteint le footer
panel.style.transform = 'translateY(0)';
}
}
window.addEventListener('scroll', checkScroll);
window.addEventListener('resize', () => {
if (window.innerWidth > responsiveSmall) {
panel.style.transform = '';
}
checkScroll();
});
checkScroll();
isInitialized = true;
}

View file

@ -1,35 +0,0 @@
let isInitialized = false;
export function btnGroupMobile() {
if (isInitialized) return;
const btnGroup = document.querySelector(".btn--group__mobile");
let footer = document.querySelector("#site-footer");
if (!btnGroup) return;
function checkScroll() {
const windowHeight = window.innerHeight;
const scrollY = window.scrollY;
const footerTop = footer.getBoundingClientRect().top;
if (scrollY > windowHeight * 0.6) {
btnGroup.classList.add('is-visible');
if (footerTop < windowHeight) {
btnGroup.classList.remove('is-visible');
}
} else {
btnGroup.classList.remove('is-visible');
}
}
window.addEventListener('scroll', checkScroll);
checkScroll();
isInitialized = true;
}

View file

@ -1,50 +0,0 @@
import Swiper from 'https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.mjs';
export function initHeroSlider() {
const heroSlider = document.querySelector('.hero-slider');
if (!heroSlider) {
return;
}
const swiper = new Swiper('.hero-slider', {
// Optional parameters
loop: true,
speed: 600,
effect: 'fade',
fadeEffect: {
crossFade: true
},
// Touch/Swipe settings (activé par défaut, mais configuré ici pour optimisation)
touchRatio: 1,
touchAngle: 45,
grabCursor: true,
simulateTouch: true,
allowTouchMove: true,
// Navigation arrows
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
// Pagination
pagination: {
el: '.swiper-pagination',
clickable: true,
},
// Keyboard control
keyboard: {
enabled: true,
},
// Accessibility
a11y: {
prevSlideMessage: 'Diapositive précédente',
nextSlideMessage: 'Diapositive suivante',
paginationBulletMessage: 'Aller à la diapositive {{index}}',
},
});
}

View file

@ -1,60 +0,0 @@
export function panelToggle(responsiveSmall) {
const toggleBtn = document.querySelector('#toggle-panel');
const toggleBtnMobile = document.querySelector('#toggle-panel__mobile');
const main = document.querySelector('main');
const closeBtn = document.querySelector('.panel-left .panel__header');
function openPanel() {
main.classList.add('panel-open');
const screenWidth = window.innerWidth;
if (screenWidth <= responsiveSmall) {
console.log("small screen");
document.body.style.overflowY = 'hidden';
}
}
function closePanel() {
main.classList.remove('panel-open');
main.classList.add('panel-close');
document.body.style.overflowY = '';
}
if (toggleBtn) {
toggleBtn.addEventListener('click', (e) => {
e.stopPropagation();
openPanel();
});
}
if (toggleBtnMobile) {
toggleBtnMobile.addEventListener('click', (e) => {
e.stopPropagation();
openPanel();
});
}
if (closeBtn) {
closeBtn.addEventListener('click', closePanel);
}
}
export function tocMobile(responsiveSmall) {
const toc = document.querySelector('#toc');
const main = document.querySelector('main');
if (!toc) return;
const tocLinks = toc.querySelectorAll('a');
tocLinks.forEach(link => {
link.addEventListener('click', () => {
if (window.innerWidth <= responsiveSmall) {
main.classList.remove('panel-open');
main.classList.add('panel-close');
document.body.style.overflowY = '';
}
});
});
}

View file

@ -1,10 +1,6 @@
import { headerToggle, headerScrollVisibility } from './header.js';
import { copyLink } from './share.js';
import { panelToggle, tocMobile } from './panel.js';
import { btnGroupMobile } from './btn-group-mobile.js';
import { bannerStickyDesktop } from './banner-sticky-desktop.js';
import { themeToggle } from './themeToggle.js';
import { initHeroSlider } from './hero-slider.js';
import { playVideo } from './hero-video.js';
import { initDropdowns } from './dropdown.js';
import { initSwipers } from './swipers.js';
@ -15,16 +11,11 @@ const responsiveSmall = 768;
window.onload = async function () {
console.log("SCRIPT LOADED");
headerToggle();
panelToggle(responsiveSmall);
themeToggle();
tocMobile(responsiveSmall);
copyLink();
btnGroupMobile(responsiveSmall)
bannerStickyDesktop(responsiveSmall);
initHeroSlider();
playVideo();
initDropdowns(responsiveSmall);
initSwipers();

View file

@ -115,7 +115,7 @@ tabs:
team:
label: Équipe Index
type: structure
width: 2/4
help: Le « rôle » saffiche entre parenthèses
columns:
name:
label: Nom

View file

@ -1,6 +1,6 @@
<?php snippet('header') ?>
<!--
<div class="btn--group__mobile">
<div class="dropdown dropdown--position-mobile">
<button class="dropdown__trigger btn--bold-inline no-link">
@ -11,7 +11,9 @@
<?php snippet('modal-share') ?>
</div>
</div>
</div>
</div> -->
<main>
@ -27,8 +29,6 @@
<div class="page__content">
<?php
$videoPreview = $page->videoPreview()->toFile();
$hasVideo = $videoPreview || $page->videoUrl()->isNotEmpty();
@ -465,10 +465,57 @@ if ($package):
</article>
<?php endforeach ?>
<div class="see-more">
<button class="btn--bold-inline">
<a href="/enquetes">
<span class="text">Voir toutes les enquêtes</span>
<span class="icon"><?= svg('assets/icons/arrow-left.svg') ?></span>
</a>
</button>
</div>
</aside>
</div>
<?php endif ?>
</main>
<div class="bottom-bar">
<div class="bottom-bar__inner">
<div class="title-group">
<p class="type">Enquête</p>
<p class="title"><?= $page->title()->esc() ?></p>
</div>
<div class="dropdown dropdown--position-mobile">
<button class="dropdown__trigger btn--simple no-link">
<span class="icon"><?= svg('assets/icons/share.svg') ?></span>
<span class="text">Partager</span>
</button>
<div class="dropdown__content">
<?php snippet('modal-share') ?>
</div>
</div>
<button class="btn--simple">
<a href="#" download>
<span class="icon"><?= svg('assets/icons/printer.svg') ?></span>
<span class="text">Télécharger</span>
</a>
</button>
<button class="btn--simple btn--support"><a targer="_blank" href="https://soutenir.index.ngo/">Soutenez-nous</a></button>
<button class="btn--simple btn--back-to-top">
<a href="#"><span class="icon"><?= svg('assets/icons/arrow-left.svg') ?></a>
</button>
</div>
</div>
<?php snippet('footer') ?>