PHP dynamique + cache JSON, nettoyage CSS/HTML, CI Forgejo

- Renommage classes/IDs (BEM cohérent, anglais, noms sémantiques)
- Correction HTML : h3→h2 FAQ, button>a→a[role=button] CTA mobile
- Conversion index.html → index.php (FR/EN) avec cache JSON depuis API Kirby
- Pages merci/thanks converties en PHP dynamique
- Ajout includes/cache.php + includes/config.php (cache TTL 5min)
- Ajout CI Forgejo (deploy FTP via lftp)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-04-12 08:00:58 +02:00
parent 119c98edab
commit 322d9136b6
29 changed files with 917 additions and 1485 deletions

View file

@ -0,0 +1,32 @@
name: Deploy
on:
push:
branches:
- main
jobs:
deploy:
name: Deploy to Production
runs-on: docker
container:
image: forgejo-ci-php:latest
steps:
- name: Checkout code
run: |
git clone --depth 1 --branch main https://oauth2:${{ github.token }}@forge.studio-variable.com/${{ github.repository }}.git .
- name: Deploy via FTP
env:
USERNAME: ${{ secrets.USERNAME }}
PASSWORD: ${{ secrets.PASSWORD }}
HOST: ${{ secrets.HOST }}
run: |
apt-get update -qq && apt-get install -y -qq lftp
cat > /tmp/lftp-script.txt <<SCRIPT
set ftp:ssl-allow no
open -u $USERNAME,$PASSWORD $HOST
mirror --reverse --verbose --ignore-time --parallel=10 -x cache/ -x .git/ -x .forgejo/ -x .claude/ -x backup/ . .
quit
SCRIPT
lftp -f /tmp/lftp-script.txt

View file

@ -1,4 +1,4 @@
#btn--don__mobile {
#donation-cta-mobile {
width: 100%;
display: flex;
align-items: center;
@ -28,7 +28,7 @@
}
}
.btn--don {
.donation-cta {
--vertical-padding: 0.5ch;
height: calc(var(--h-block) + var(--vertical-padding));
border-radius: calc(var(--h-block) / 1);

View file

@ -1,4 +1,4 @@
.form__newsletter{
.newsletter-form{
--size: 24px;
position: relative;

View file

@ -1,4 +1,4 @@
.gauge__container {
.gauge-container {
width: 100%;
display: flex;
flex-wrap: wrap;
@ -36,7 +36,7 @@
}
}
.gauge--infos {
.gauge-info {
.property {
font-size: var(--fs-small);
padding-bottom: 3px;
@ -51,7 +51,7 @@
}
}
#gauge--infos__donors {
#gauge-info--supporters {
text-align: center;
display: flex;
flex-direction: column;
@ -79,7 +79,7 @@
}
}
.gauge--infos {
.gauge-info {
.property {
font-size: var(--fs-small);
}

View file

@ -3,7 +3,7 @@
[data-template="support"],
[data-template="store"]{
.p__baseline-big{
.hero-heading{
font-family: var(--title);
font-size: var(--fs-big);
font-weight: var(--fw-bold);
@ -32,7 +32,7 @@
}
}
.p__baseline{
.subheading{
font-size: var(--fs-medium);
font-weight: var(--fw-medium);
line-height: 1.1;
@ -44,13 +44,13 @@
}
}
.p__details{
.text-details{
font-size: var(--fs-small);
margin-bottom: 0.5em;
color: var(--grey-400);
}
.section__heading{
.section-heading{
font-size: var(--fs-normal);
font-weight: var(--fw-medium);
line-height: 1;

View file

@ -19,12 +19,12 @@
}
}
.p__small{
.text-small{
font-size: var(--fs-x-small);
// margin-top: calc(var(--spacing)*0.5)
}
#list-socials {
#socials-list {
list-style: none;
columns: 2;
max-width: 500px;
@ -68,10 +68,10 @@
@media #{$small}{
margin-top: calc(var(--spacing)*2);
.footer__socials{
.footer-socials{
margin-top: calc(var(--spacing)*1.5);
}
.footer__mentions{
.footer-mentions{
margin-top: calc(var(--spacing)*0.5);
p{
// font-size: var(--font-size);
@ -83,7 +83,7 @@
@media #{$small-up}{
.site-footer__container{
.footer-container{
display: grid;
grid-template-columns: 1fr 1fr;
column-gap: calc(var(--spacing)*2);
@ -92,7 +92,7 @@
margin: 0 auto;
}
.footer__mentions{
.footer-mentions{
grid-column: span 2;
text-align: center;
p{
@ -105,13 +105,13 @@
}
@media #{$medium-up}{
.site-footer__container{
.footer-container{
column-gap: calc(var(--spacing)*4);
}
}
@media #{$small}{
.footer__mentions{
.footer-mentions{
padding-top: calc(var(--spacing)*1);
p{ margin-top: 0;}

File diff suppressed because one or more lines are too long

View file

@ -3,7 +3,7 @@
margin-bottom: calc(var(--spacing) * 2);
}
.p__baseline-big {
.hero-heading {
margin-top: calc(var(--spacing) * 2);
}

View file

@ -79,7 +79,7 @@
padding-top: calc(var(--spacing) * 0.5);
border-top: var(--border-light);
.p__baseline-big {
.hero-heading {
margin: 0;
text-align: left;
}

View file

@ -1,11 +1,11 @@
[data-template="thanks"]{
.p__baseline-big {
.hero-heading {
margin-top: calc(var(--spacing) * 3);
margin-bottom: calc(var(--spacing) * 3);
// font-size: var(--fs-x-big);
}
.p__baseline {
.subheading {
// font-size: var(--fs-big);
text-align: left;
max-width: 800px;

View file

@ -11,7 +11,7 @@
margin-bottom: calc(var(--spacing)*4);
.form__newsletter{
.newsletter-form{
margin: calc(var(--spacing)*1) 0;
input[type="email"]{
@ -34,13 +34,13 @@
}
}
.p__baseline{
.subheading{
max-width: 52ch;
// margin: 0 auto;
text-align: left;
}
.p__details{
.text-details{
color: var(--color-txt);
max-width: 80ch;
}

View file

@ -63,7 +63,7 @@
padding: calc(var(--spacing)*0.5) 0;
}
.gauge__container{
.gauge-container{
padding-top: calc(var(--spacing)*1);
}

View file

@ -1,5 +1,5 @@
.comment__text{
.comment-text{
font-size: var(--fs-medium);
font-weight: var(--fw-medium);
line-height: var(--leading-tight);
@ -8,7 +8,7 @@
text-align: center;
}
.comment__name {
.comment-name {
margin-top: calc(var(--spacing)*0.5);
text-align: center;
}
@ -29,7 +29,7 @@
align-items: center;
}
.comments-slider__dots{
.comments-dots{
position: absolute;
bottom: 10px; /* espace du bas */
left: 0;

View file

@ -5,7 +5,7 @@
.btn--donation__container{
.donation-grid{
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: calc(var(--padding-body)*0.75);
@ -19,7 +19,7 @@
max-width: 420px;
}
.btn--donation__grow-2{
.donation-btn--full{
grid-column: span 2;
}
@ -30,7 +30,7 @@
}
.btn--donation{
.donation-btn{
background-color: var(--color-txt);
color: var(--color-bg);
border-radius: var(--radius-small);

View file

@ -1,7 +1,7 @@
#section__video{
margin-bottom: calc(var(--spacing)*2);
.btn__deploy{
.btn-expand{
margin-top: calc(var(--spacing)*1);
--size: var(--h-block);
font-family: var(--font);
@ -45,13 +45,13 @@
}
.videos__ul{
.testimonies-list{
list-style: none;
width: 100%;
margin-top: calc(var(--spacing)*1);
display: none;
.videos__li{
.testimony-item{
position: relative;
padding-left: 40px;
@ -66,7 +66,7 @@
cursor: pointer;
@media screen and (max-width: 520px){
.br-desktop{ display: none; }
.desktop-break{ display: none; }
}
@ -96,9 +96,9 @@
}
}
#videos__input{ display: none }
#testimonies-toggle{ display: none }
#videos__input:checked ~ .videos__ul{
#testimonies-toggle:checked ~ .testimonies-list{
display: block;
}
}

View file

@ -74,7 +74,7 @@
function initTabs() {
const tabButtons = document.querySelectorAll('.nav--tabs__btn');
const containers = document.querySelectorAll('.btn--donation__container');
const containers = document.querySelectorAll('.donation-grid');
tabButtons.forEach((button, index) => {
button.addEventListener('click', () => {
@ -91,9 +91,9 @@
function initDonationButtons() {
const oneOffContainer = document.querySelector(
'[data-donnation="one-off"]'
'[data-donation="one-off"]'
);
const oneOffButtons = oneOffContainer.querySelectorAll('.btn--donation');
const oneOffButtons = oneOffContainer.querySelectorAll('.donation-btn');
oneOffButtons.forEach((button, index) => {
if (index < AMOUNTS.oneOff.length) {
@ -118,9 +118,9 @@
});
const monthlyContainer = document.querySelector(
'[data-donnation="monthly"]'
'[data-donation="monthly"]'
);
const monthlyButtons = monthlyContainer.querySelectorAll('.btn--donation');
const monthlyButtons = monthlyContainer.querySelectorAll('.donation-btn');
monthlyButtons.forEach((button, index) => {
if (index < AMOUNTS.monthly.length) {

View file

@ -45,7 +45,7 @@ function updateGaugeDisplay(campaignData) {
}
const countElement = document.querySelector(
'#gauge--infos__donateurs .value'
'#gauge-info--supporters .value'
);
if (countElement) {
countElement.textContent = totalSupport;

View file

@ -81,7 +81,7 @@
}
function initNewsletterForms() {
const forms = document.querySelectorAll('.form__newsletter');
const forms = document.querySelectorAll('.newsletter-form');
forms.forEach((form) => form.addEventListener('submit', handleFormSubmit));
}

View file

@ -27,7 +27,7 @@ function headerShrink() {
}
function toggleDonationButton() {
const btn = document.getElementById('btn--don__mobile');
const btn = document.getElementById('donation-cta-mobile');
const section = document.getElementById('section__donation');
const footer = document.getElementById('site-footer');
@ -61,7 +61,7 @@ function videos(){
let section = document.getElementById("section__video");
console.log(section);
let videoslinks = document.querySelectorAll(".videos__li");
let videoslinks = document.querySelectorAll(".testimony-item");
videoslinks.forEach(function (video, index) {
video.addEventListener("click", (event) => {

View file

@ -89,36 +89,36 @@
<main>
<div class="col-left">
<section id="section__hero">
<p class="p__baseline-big">
<p class="hero-heading">
To keep investigating, <br />Index needs your help
</p>
<div class="gauge__container">
<div class="gauge-container">
<div id="gauge" style="--pourcent: 0%"></div>
<div class="gauge--infos" id="gauge--infos__donateurs">
<div class="gauge-info" id="gauge-info--supporters">
<p class="property">Regular supporters</p>
<p class="value">0</p>
</div>
<div class="gauge--infos" id="gauge--infos__objectif">
<div class="gauge-info" id="gauge-info--goal">
<p class="property">Goal</p>
<p class="value">500</p>
</div>
</div>
<p class="p__baseline-big">
<p class="hero-heading">
Goal: 500 Supporters<br /><strong>by 21 June 2026</strong>
</p>
</section>
<section id="section__baseline">
<p class="p__baseline">
<p class="subheading">
Index is a not-for-profit, <br />digital investigation NGO.<br />Your
support guarantees our independence.
</p>
</section>
<section id="section__video">
<h2 class="section__heading">Why support Index? Hear from those at the heart of it.</h2>
<h2 class="section-heading">Why support Index? Hear from those at the heart of it.</h2>
<div class="video-container">
<iframe
src="https://player.vimeo.com/video/1136957715?h=215c38e160&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479&autoplay=1"
@ -131,7 +131,7 @@
</section>
<section id="section__questions">
<h3 class="section__heading">Frequently Asked Questions</h3>
<h2 class="section-heading">Frequently Asked Questions</h2>
<details>
<summary>What are Index Supporters?</summary>
@ -343,49 +343,49 @@
</nav>
<div
data-donnation="one-off"
class="btn--donation__container"
data-donation="one-off"
class="donation-grid"
>
<button class="btn--donation">
<button class="donation-btn">
<p class="bold">200&#8239;</p>
<p class="small">That is 68&#8239;€ after tax</p>
</button>
<button class="btn--donation btn--donation__grow-1">
<button class="donation-btn donation-btn--wide">
<p class="bold">100&#8239;</p>
<p class="small">That is 34&#8239;€ after tax</p>
</button>
<button class="btn--donation btn--donation__grow-1">
<button class="donation-btn donation-btn--wide">
<p class="bold">50&#8239;</p>
<p class="small">That is 17&#8239;€ after tax</p>
</button>
<button class="btn--donation btn--donation__grow-1">
<button class="donation-btn donation-btn--wide">
<p class="bold">20&#8239;</p>
<p class="small">That is 6.80&#8239;€ after tax</p>
</button>
<button class="btn--donation btn--donation__grow-2">
<button class="donation-btn donation-btn--full">
<p class="bold">Choose your amount</p>
<p class="small">With 66&#8239;% tax deduction</p>
</button>
</div>
<div data-donnation="monthly" class="btn--donation__container is-selected">
<button class="btn--donation">
<div data-donation="monthly" class="donation-grid is-selected">
<button class="donation-btn">
<p class="bold">5€/month</p>
<p class="small">That is X€ after taxes</p>
</button>
<button class="btn--donation btn--donation__grow-1">
<button class="donation-btn donation-btn--wide">
<p class="bold">10€/month</p>
<p class="small">That is X€ after taxes</p>
</button>
<button class="btn--donation btn--donation__grow-1">
<button class="donation-btn donation-btn--wide">
<p class="bold">20€/month</p>
<p class="small">That is X€ after taxes</p>
</button>
<button class="btn--donation btn--donation__grow-1">
<button class="donation-btn donation-btn--wide">
<p class="bold">50€/month</p>
<p class="small">That is X€ after taxes</p>
</button>
<button class="btn--donation btn--donation__grow-2">
<button class="donation-btn donation-btn--full">
<p class="bold">Choose your amount</p>
<p class="small">With tax deduction</p>
</button>
@ -393,60 +393,59 @@
</section>
<section id="section__comments">
<h2 class="section__heading">Donor comments</h2>
<h2 class="section-heading">Donor comments</h2>
<div class="swiper" id="comments-slider">
<div class="swiper-wrapper">
<div class="swiper-slide comment">
<p class="comment__text">
<p class="comment-text">
You are doing admirable work. Thank you for helping Justice
with a capital J. Keep up the good work!
</p>
<p class="comment__name">Olivier</p>
<p class="comment-name">Olivier</p>
</div>
<div class="swiper-slide comment">
<p class="comment__text">
<p class="comment-text">
Thank you for the beneficial, valuable, and extremely
professional work you do.
</p>
<p class="comment__name">Myriam</p>
<p class="comment-name">Myriam</p>
</div>
<div class="swiper-slide comment">
<p class="comment__text">
<p class="comment-text">
You are truly serving the public good, and the methods you use
deserve to be widely known.
</p>
<p class="comment__name">Frédéric</p>
<p class="comment-name">Frédéric</p>
</div>
<div class="swiper-slide comment">
<p class="comment__text">
<p class="comment-text">
Thank you for continuing your tireless quest to reveal the
truths that are being kept from us.
</p>
<p class="comment__name">Pauline</p>
<p class="comment-name">Pauline</p>
</div>
<div class="swiper-slide comment">
<p class="comment__text">
<p class="comment-text">
Index investigators do essential work for democracy and
justice. Through this citizen support, I express my gratitude
for their commitment and rigor.
</p>
<p class="comment__name">Anne</p>
<p class="comment-name">Anne</p>
</div>
</div>
<div class="swiper-pagination comments-slider__dots"></div>
<div class="swiper-pagination comments-dots"></div>
</div>
</section>
</div>
<div id="btn--don__mobile">
<button class="btn--don">
<a href="#section__donation">
<div id="donation-cta-mobile">
<a href="#section__donation" class="donation-cta" role="button">
<span class="txt">Donate</span>
<span class="icon">
<svg
@ -463,21 +462,20 @@
/>
</svg>
</span>
</a>
</button>
</a>
</div>
</main>
<footer id="site-footer">
<div class="site-footer__container">
<div class="footer__newsletter">
<div class="footer-container">
<div class="footer-newsletter">
<p>
Receive the latest investigation and news from Index directly in
your inbox.
</p>
<p>Sign up for the newsletter</p>
<form class="form__newsletter">
<form class="newsletter-form">
<input
type="email"
name="email"
@ -504,7 +502,7 @@
</button>
</form>
<p class="p__small">
<p class="text-small">
By signing up, you agree to Index's
<a target="_blank" href="https://www.index.ngo/mentions-legales/"
>terms of use</a
@ -512,10 +510,10 @@
</p>
</div>
<div class="footer__socials">
<div class="footer-socials">
<p>Follow Index on social media</p>
<ul id="list-socials">
<ul id="socials-list">
<li>
<a
href="https://www.youtube.com/index-ngo"
@ -696,8 +694,8 @@
</ul>
</div>
<div class="footer__mentions">
<p class="p__small">
<div class="footer-mentions">
<p class="text-small">
© 2025 Index Investigation |
<a target="_blank" href="https://www.index.ngo/mentions-legales/"
>Legal notices</a
@ -716,7 +714,7 @@
disableOnInteraction: false,
},
pagination: {
el: '.comments-slider__dots',
el: '.comments-dots',
clickable: true,
},
});

270
en/index.php Normal file
View file

@ -0,0 +1,270 @@
<?php
require_once __DIR__ . '/../includes/cache.php';
$data = getSoutenirContent('en');
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><?= htmlspecialchars($data['metaTitle'] ?? 'Support Index') ?></title>
<meta name="description" content="<?= htmlspecialchars($data['metaDescription'] ?? '') ?>" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.css" />
<script src="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.js"></script>
<link rel="icon" type="image/png" href="/assets/favicon.png" />
<link rel="stylesheet" type="text/css" href="/assets/fonts/stylesheet.css" />
<link rel="stylesheet" type="text/css" href="/assets/css/style.css" />
<script src="/assets/js/onload.js"></script>
<script src="/assets/js/temp/includeHtml.js"></script>
<script src="/assets/js/donorbox-gauge.js"></script>
<script src="/assets/js/donation.js"></script>
<script src="/assets/js/newsletter-brevo.js"></script>
<meta name="robots" content="index, nofollow" />
</head>
<body data-template="support">
<header id="site-header">
<div class="header-left"></div>
<div class="header-center">
<h1 class="site-title">
<a href="https://www.index.ngo/en" aria-label="Back to home" title="go to Index website">
<svg width="100%" height="100%" viewBox="0 0 162 29" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<title>Index.ngo</title>
<g transform="matrix(1.04516,0,0,0.659091,57.4839,-6.59091)">
<rect x="-55" y="10" width="155" height="44" style="fill:none"/>
<clipPath id="_clip1"><rect x="-55" y="10" width="155" height="44"/></clipPath>
<g clip-path="url(#_clip1)">
<g transform="matrix(0.95679,0,0,1.51724,-55,10)">
<path d="M162,29L148.198,29L141.174,20.767L134.15,29L91.184,29L91.184,0.004L120.653,0.004L120.653,7.351L102.637,7.351L102.637,10.867L120.137,10.867L120.137,18.13L102.637,18.13L102.637,21.606L120.926,21.606L120.926,28.951L134.273,14.414L120.807,0L134.56,0L141.388,7.767L147.76,0L161.201,0L148.236,13.79L161.996,28.997L162,29ZM68.58,29L54.224,29L54.224,0.004L68.637,0.004C74.672,0.004 78.31,0.004 82.046,2.045C86.259,4.379 88.674,8.889 88.674,14.417C88.674,19.406 86.862,23.405 83.427,25.975C79.463,29 75.345,29 68.58,29ZM49.819,29L38.775,29L31.499,19.815C29.746,17.735 28.088,15.545 27.307,14.495C27.387,15.813 27.524,17.238 27.524,20.499L27.524,29L15.965,29L15.965,0.004L27.009,0.004L33.798,8.349C36.223,11.121 37.709,12.993 38.393,13.881C38.347,12.615 38.26,9.911 38.26,6.84L38.26,0.004L49.819,0.004L49.819,29ZM11.559,29L0,29L0,0.004L11.559,0.004L11.559,29ZM65.784,21.818L67.904,21.818C70.918,21.818 73.067,21.818 74.728,20.531C76.074,19.491 76.845,17.308 76.845,14.541C76.845,11.526 76.084,9.541 74.525,8.476C72.895,7.411 71.461,7.224 67.578,7.224L65.784,7.224L65.784,21.818Z" style="fill-rule:nonzero"/>
</g>
</g>
</g>
</svg>
</a>
</h1>
</div>
<div class="header-right">
<ul id="toggle-lang">
<li><a href="../">Fr</a></li>
<li class="is-selected"><a href="./">En</a></li>
</ul>
</div>
</header>
<main>
<div class="col-left">
<section id="section__hero">
<p class="hero-heading"><?= $data['heroHeading'] ?? '' ?></p>
<div class="gauge-container">
<div id="gauge" style="--pourcent: 0%"></div>
<div class="gauge-info" id="gauge-info--supporters">
<p class="property">Regular supporters</p>
<p class="value">0</p>
</div>
<div class="gauge-info" id="gauge-info--goal">
<p class="property">Goal</p>
<p class="value">500</p>
</div>
</div>
<p class="hero-heading">
<?= htmlspecialchars($data['heroObjectiveLabel'] ?? '') ?><br />
<strong><?= htmlspecialchars($data['heroObjectiveDate'] ?? '') ?></strong>
</p>
</section>
<section id="section__baseline">
<p class="subheading"><?= $data['subheading'] ?? '' ?></p>
</section>
<section id="section__video">
<h2 class="section-heading"><?= $data['videoSectionHeading'] ?? '' ?></h2>
<div class="video-container">
<iframe
title="Campaign video"
src="<?= htmlspecialchars($data['mainVideoUrl'] ?? '') ?>"
style="aspect-ratio: 9/16; width: 100%; border: 0"
allow="autoplay; fullscreen; picture-in-picture"
allowfullscreen
></iframe>
</div>
<?php if (!empty($data['testimonies'])): ?>
<input type="checkbox" id="testimonies-toggle" />
<label class="btn-expand" for="testimonies-toggle">
<span class="txt"><?= htmlspecialchars($data['testimoniesButtonLabel'] ?? 'Watch testimonies') ?></span>
<span class="icon"><svg width="34px" height="34px" viewBox="0 0 16 13" version="1.1" xmlns="http://www.w3.org/2000/svg" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<rect x="0" y="0" width="15.43" height="12.636" style="fill:none"/>
<path d="M0,7.29L0,5.373L9.801,5.373C10.67,5.373 11.757,5.4 12.387,5.427C11.952,5.022 11.366,4.455 10.888,3.969L8.432,1.404L9.366,0L15.43,6.318L9.366,12.636L8.432,11.232L10.888,8.667C11.366,8.181 11.952,7.614 12.387,7.236C11.757,7.263 10.67,7.29 9.801,7.29L0,7.29Z" style="fill-rule:nonzero"/>
</svg></span>
</label>
<ul class="testimonies-list">
<?php foreach ($data['testimonies'] as $testimony): ?>
<li class="testimony-item" data-video="<?= htmlspecialchars($testimony['videoUrl']) ?>">
<span class="icon">
<svg height="80px" width="80px" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
<path d="M500.203,236.907L30.869,2.24c-6.613-3.285-14.443-2.944-20.736,0.939C3.84,7.083,0,13.931,0,21.333v469.333 c0,7.403,3.84,14.251,10.133,18.155c3.413,2.112,7.296,3.179,11.2,3.179c3.264,0,6.528-0.747,9.536-2.24l469.333-234.667 C507.435,271.467,512,264.085,512,256S507.435,240.533,500.203,236.907z"/>
</svg>
</span>
<p class="txt"><?= $testimony['description'] ?></p>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</section>
<section id="section__questions">
<h2 class="section-heading"><?= htmlspecialchars($data['faqHeading'] ?? 'Frequently Asked Questions') ?></h2>
<?php foreach (($data['questions'] ?? []) as $q): ?>
<details>
<summary><?= htmlspecialchars($q['question']) ?></summary>
<?= $q['answer'] ?>
</details>
<?php endforeach; ?>
</section>
</div>
<div class="col-right">
<section id="section__donation">
<nav class="nav--tabs">
<button class="nav--tabs__btn is-selected">Monthly donation</button>
<button class="nav--tabs__btn">One-time donation</button>
</nav>
<div data-donation="one-off" class="donation-grid">
<button class="donation-btn">
<p class="bold">200&#8239;€</p>
<p class="small">That is 68&#8239;€ after tax</p>
</button>
<button class="donation-btn donation-btn--wide">
<p class="bold">100&#8239;€</p>
<p class="small">That is 34&#8239;€ after tax</p>
</button>
<button class="donation-btn donation-btn--wide">
<p class="bold">50&#8239;€</p>
<p class="small">That is 17&#8239;€ after tax</p>
</button>
<button class="donation-btn donation-btn--wide">
<p class="bold">20&#8239;€</p>
<p class="small">That is 6.80&#8239;€ after tax</p>
</button>
<button class="donation-btn donation-btn--full">
<p class="bold">Choose your amount</p>
<p class="small">With 66&#8239;% tax deduction</p>
</button>
</div>
<div data-donation="monthly" class="donation-grid is-selected">
<button class="donation-btn">
<p class="bold">5/month</p>
<p class="small">That is X€ after taxes</p>
</button>
<button class="donation-btn donation-btn--wide">
<p class="bold">10/month</p>
<p class="small">That is X€ after taxes</p>
</button>
<button class="donation-btn donation-btn--wide">
<p class="bold">20/month</p>
<p class="small">That is X€ after taxes</p>
</button>
<button class="donation-btn donation-btn--wide">
<p class="bold">50/month</p>
<p class="small">That is X€ after taxes</p>
</button>
<button class="donation-btn donation-btn--full">
<p class="bold">Choose your amount</p>
<p class="small">With tax deduction</p>
</button>
</div>
</section>
<section id="section__comments">
<h2 class="section-heading"><?= htmlspecialchars($data['commentsHeading'] ?? 'Donor comments') ?></h2>
<div class="swiper" id="comments-slider">
<div class="swiper-wrapper">
<?php foreach (($data['comments'] ?? []) as $comment): ?>
<div class="swiper-slide">
<p class="comment-text"><?= htmlspecialchars($comment['text']) ?></p>
<p class="comment-name"><?= htmlspecialchars($comment['name']) ?></p>
</div>
<?php endforeach; ?>
</div>
<div class="swiper-pagination comments-dots"></div>
</div>
</section>
</div>
<div id="donation-cta-mobile">
<a href="#section__donation" class="donation-cta" role="button">
<span class="txt">Donate</span>
<span class="icon">
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m14.523 18.787s4.501-4.505 6.255-6.26c.146-.146.219-.338.219-.53s-.073-.383-.219-.53c-1.753-1.754-6.255-6.258-6.255-6.258-.144-.145-.334-.217-.524-.217-.193 0-.385.074-.532.221-.293.292-.295.766-.004 1.056l4.978 4.978h-14.692c-.414 0-.75.336-.75.75s.336.75.75.75h14.692l-4.979 4.979c-.289.289-.286.762.006 1.054.148.148.341.222.533.222.19 0 .378-.072.522-.215z" fill-rule="nonzero"/>
</svg>
</span>
</a>
</div>
</main>
<footer id="site-footer">
<div class="footer-container">
<div class="footer-newsletter">
<p><?= $data['footerNewsletterText'] ?? '' ?></p>
<form class="newsletter-form">
<input type="email" name="email" placeholder="Your email address" required />
<button class="btn--bold" type="submit" aria-label="subscribe">
<span class="txt"><?= htmlspecialchars($data['footerNewsletterCta'] ?? 'Subscribe') ?></span>
<span class="icon">
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m14.523 18.787s4.501-4.505 6.255-6.26c.146-.146.219-.338.219-.53s-.073-.383-.219-.53c-1.753-1.754-6.255-6.258-6.255-6.258-.144-.145-.334-.217-.524-.217-.193 0-.385.074-.532.221-.293.292-.295.766-.004 1.056l4.978 4.978h-14.692c-.414 0-.75.336-.75.75s.336.75.75.75h14.692l-4.979 4.979c-.289.289-.286.762.006 1.054.148.148.341.222.533.222.19 0 .378-.072.522-.215z" fill-rule="nonzero"/>
</svg>
</span>
</button>
</form>
<p class="text-small"><?= $data['footerNewsletterDisclaimer'] ?? '' ?></p>
</div>
<div class="footer-socials">
<p><?= htmlspecialchars($data['footerSocialsHeading'] ?? '') ?></p>
<ul id="socials-list">
<?php foreach (($data['footerSocials'] ?? []) as $social): ?>
<li>
<a href="<?= htmlspecialchars($social['url']) ?>" target="_blank" rel="noopener noreferrer">
<span class="icon"><?= $social['svgIcon'] ?></span>
<span class="text"><?= htmlspecialchars($social['name']) ?></span>
</a>
</li>
<?php endforeach; ?>
</ul>
</div>
<div class="footer-mentions">
<p class="text-small"><?= $data['footerMentions'] ?? '' ?></p>
</div>
</div>
</footer>
<script>
const swiper = new Swiper('#comments-slider', {
slidesPerView: 1,
loop: true,
autoplay: {
delay: 4000,
disableOnInteraction: false,
},
pagination: {
el: '.comments-dots',
clickable: true,
},
});
</script>
</body>
</html>

42
includes/cache.php Normal file
View file

@ -0,0 +1,42 @@
<?php
require_once __DIR__ . '/config.php';
function getSoutenirContent(string $lang = 'fr'): array {
$cacheFile = CACHE_DIR . "/content.{$lang}.json";
// Serve cache if fresh
if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < CACHE_TTL) {
return json_decode(file_get_contents($cacheFile), true) ?: [];
}
// Fetch from Kirby API
$url = KIRBY_API_URL . '?lang=' . urlencode($lang);
if (SOUTIEN_API_TOKEN) {
$url .= '&token=' . urlencode(SOUTIEN_API_TOKEN);
}
$context = stream_context_create([
'http' => [
'timeout' => 5,
'header' => "Referer: https://soutenir.index.ngo\r\n",
],
]);
$response = @file_get_contents($url, false, $context);
if ($response !== false) {
$data = json_decode($response, true);
if ($data && !isset($data['error'])) {
@file_put_contents($cacheFile, $response, LOCK_EX);
return $data;
}
}
// Fallback: serve stale cache rather than nothing
if (file_exists($cacheFile)) {
return json_decode(file_get_contents($cacheFile), true) ?: [];
}
return [];
}

6
includes/config.php Normal file
View file

@ -0,0 +1,6 @@
<?php
define('KIRBY_API_URL', 'https://www.index.ngo/api/soutien-content');
define('SOUTIEN_API_TOKEN', ''); // À remplir avec le même token que dans la config Kirby
define('CACHE_TTL', 300); // 5 minutes
define('CACHE_DIR', __DIR__ . '/../cache');

View file

@ -90,36 +90,36 @@
<main>
<div class="col-left">
<section id="section__hero">
<p class="p__baseline-big">
<p class="hero-heading">
Pour continuer à enquêter, <br />Index a besoin de vous
</p>
<div class="gauge__container">
<div class="gauge-container">
<div id="gauge" style="--pourcent: 0%"></div>
<div class="gauge--infos" id="gauge--infos__donateurs">
<div class="gauge-info" id="gauge-info--supporters">
<p class="property">Soutiens réguliers</p>
<p class="value">0</p>
</div>
<div class="gauge--infos" id="gauge--infos__objectif">
<div class="gauge-info" id="gauge-info--goal">
<p class="property">Objectif</p>
<p class="value">500</p>
</div>
</div>
<p class="p__baseline-big">
<p class="hero-heading">
Objectif 500 Soutiens<br /><strong>au 21 juin 2026</strong>
</p>
</section>
<section id="section__baseline">
<p class="p__baseline">
<p class="subheading">
Index est une ONG dinvestigation <br />à&nbsp;but non-lucratif.
<br />Vos dons garantissent notre indépendance.
</p>
</section>
<section id="section__video">
<h2 class="section__heading">
<h2 class="section-heading">
Pourquoi soutenir Index&#8239; ? <br />Écoutez les premier·es
concerné·es
</h2>
@ -133,8 +133,8 @@
></iframe>
</div>
<input type="checkbox" id="videos__input" />
<label class="btn__deploy" for="videos__input">
<input type="checkbox" id="testimonies-toggle" />
<label class="btn-expand" for="testimonies-toggle">
<span class="txt">Voir les témoignages</span>
<span class="icon"
><svg
@ -169,9 +169,9 @@
></span>
</label>
<ul class="videos__ul">
<ul class="testimonies-list">
<li
class="videos__li"
class="testimony-item"
data-video="https://player.vimeo.com/video/1138884807?h=384a2d15ea&autoplay=1"
>
<span class="icon">
@ -192,13 +192,13 @@
<p class="txt">
«&#8239;Index fait un travail que&nbsp;la&nbsp;justice
ne&nbsp;fait pas »&#8239;:
<span class="br-desktop"><br /></span>le&nbsp;témoignage
<span class="desktop-break"><br /></span>le&nbsp;témoignage
dIssam&nbsp;El&nbsp;Khalfaoui
</p>
</li>
<li
class="videos__li"
class="testimony-item"
data-video="https://player.vimeo.com/video/1145581831?h=ce46358189&autoplay=1"
>
<span class="icon">
@ -224,7 +224,7 @@
</li>
<li
class="videos__li"
class="testimony-item"
data-video="https://player.vimeo.com/video/1142401468?h=f88778b3dd&autoplay=1"
>
<span class="icon">
@ -244,13 +244,13 @@
</span>
<p class="txt">
«&#8239;Les enquêtes d'Index doivent continuer&#8239;»&#8239;:
<span class="br-desktop"><br /></span>le&nbsp;témoignage
<span class="desktop-break"><br /></span>le&nbsp;témoignage
dAssa&nbsp;Traoré
</p>
</li>
<li
class="videos__li"
class="testimony-item"
data-video="https://player.vimeo.com/video/1143395847?h=f28d317c46&autoplay=1"
>
<span class="icon">
@ -271,13 +271,13 @@
<p class="txt">
«&#8239;Vous faites un travail rare
et&nbsp;concret&#8239;»&#8239;:
<span class="br-desktop"><br /></span>le&nbsp;témoignage
<span class="desktop-break"><br /></span>le&nbsp;témoignage
de&nbsp;Jérôme&nbsp;Rodrigues
</p>
</li>
<li
class="videos__li"
class="testimony-item"
data-video="https://player.vimeo.com/video/1144550389?h=5781ebef9b&autoplay=1"
>
<span class="icon">
@ -297,13 +297,13 @@
</span>
<p class="txt">
«&#8239;Index est dun intérêt public absolu&#8239;»&#8239;:
<span class="br-desktop"><br /></span>le&nbsp;témoignage
<span class="desktop-break"><br /></span>le&nbsp;témoignage
de&nbsp;Fatiha&nbsp;B.
</p>
</li>
<li
class="videos__li"
class="testimony-item"
data-video="https://player.vimeo.com/video/1145649552?h=63bd03334b&autoplay=1"
>
<span class="icon">
@ -324,13 +324,13 @@
<p class="txt">
«&#8239;Je naurais jamais imaginé recevoir un&nbsp;tel
soutien&#8239;»&#8239;:
<span class="br-desktop"><br /></span>le&nbsp;témoignage
<span class="desktop-break"><br /></span>le&nbsp;témoignage
de&nbsp;Jean-François&nbsp;Martin
</p>
</li>
<li
class="videos__li"
class="testimony-item"
data-video="https://player.vimeo.com/video/1146620554?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479&autoplay=1"
>
<span class="icon">
@ -351,13 +351,13 @@
<p class="txt">
«&#8239;Le travail d'Index a permis de rétablir
la&nbsp;vérité&#8239;»&#8239;:
<span class="br-desktop"><br /></span>le&nbsp;témoignage de
<span class="desktop-break"><br /></span>le&nbsp;témoignage de
Mahamadou&nbsp;Camara, frère de&nbsp;Gaye
</p>
</li>
<li
class="videos__li"
class="testimony-item"
data-video="https://player.vimeo.com/video/1148007280?h=2e9c81e900&autoplay=1"
>
<span class="icon">
@ -378,7 +378,7 @@
<p class="txt">
«&#8239;Pour les familles endeuillées, Index est
essentiel&#8239;»&#8239;:
<span class="br-desktop"><br /></span>le&nbsp;témoignage de
<span class="desktop-break"><br /></span>le&nbsp;témoignage de
Christelle Vendeiro-Bico, belle-sœur de Luis&nbsp;Bico
</p>
</li>
@ -396,7 +396,7 @@
</section> -->
<section id="section__questions">
<h3 class="section__heading">Questions fréquentes</h3>
<h2 class="section-heading">Questions fréquentes</h2>
<details>
<summary>Les Soutiens d'Index, c'est quoi ?</summary>
@ -618,49 +618,49 @@
</nav>
<div
data-donnation="one-off"
class="btn--donation__container"
data-donation="one-off"
class="donation-grid"
>
<button class="btn--donation">
<button class="donation-btn">
<p class="bold">200&#8239;</p>
<p class="small">Soit 68&#8239;€ après impôts</p>
</button>
<button class="btn--donation btn--donation__grow-1">
<button class="donation-btn donation-btn--wide">
<p class="bold">100&#8239;</p>
<p class="small">Soit 34&#8239;€ après impôts</p>
</button>
<button class="btn--donation btn--donation__grow-1">
<button class="donation-btn donation-btn--wide">
<p class="bold">50&#8239;</p>
<p class="small">Soit 17&#8239;€ après impôts</p>
</button>
<button class="btn--donation btn--donation__grow-1">
<button class="donation-btn donation-btn--wide">
<p class="bold">20&#8239;</p>
<p class="small">Soit 6.80&#8239;€ après impôts</p>
</button>
<button class="btn--donation btn--donation__grow-2">
<button class="donation-btn donation-btn--full">
<p class="bold">Choisissez votre montant</p>
<p class="small">Avec déduction fiscale de 66&#8239;%</p>
</button>
</div>
<div data-donnation="monthly" class="btn--donation__container is-selected">
<button class="btn--donation">
<div data-donation="monthly" class="donation-grid is-selected">
<button class="donation-btn">
<p class="bold">5€/mois</p>
<p class="small">Soit X€ après impôts</p>
</button>
<button class="btn--donation btn--donation__grow-1">
<button class="donation-btn donation-btn--wide">
<p class="bold">10€/mois</p>
<p class="small">Soit X€ après impôts</p>
</button>
<button class="btn--donation btn--donation__grow-1">
<button class="donation-btn donation-btn--wide">
<p class="bold">20€/mois</p>
<p class="small">Soit X€ après impôts</p>
</button>
<button class="btn--donation btn--donation__grow-1">
<button class="donation-btn donation-btn--wide">
<p class="bold">50€/mois</p>
<p class="small">Soit X€ après impôts</p>
</button>
<button class="btn--donation btn--donation__grow-2">
<button class="donation-btn donation-btn--full">
<p class="bold">Choisissez votre montant</p>
<p class="small">Avec déduction fiscale</p>
</button>
@ -668,60 +668,59 @@
</section>
<section id="section__comments">
<h2 class="section__heading">Commentaires de donateur·ices</h2>
<h2 class="section-heading">Commentaires de donateur·ices</h2>
<div class="swiper" id="comments-slider">
<div class="swiper-wrapper">
<div class="swiper-slide comment">
<p class="comment__text">
<p class="comment-text">
Vous faites un travail admirable. Merci de faire avancer la
Justice avec un grand J. Force à vous!
</p>
<p class="comment__name">Olivier</p>
<p class="comment-name">Olivier</p>
</div>
<div class="swiper-slide comment">
<p class="comment__text">
<p class="comment-text">
Merci du travail salutaire, précieux et extrêmement
professionnel que vous réalisez.
</p>
<p class="comment__name">Myriam</p>
<p class="comment-name">Myriam</p>
</div>
<div class="swiper-slide comment">
<p class="comment__text">
<p class="comment-text">
Vous êtes vraiment d'utilité publique et les méthodes que vous
utilisez méritent d'être popularisées.
</p>
<p class="comment__name">Frédéric</p>
<p class="comment-name">Frédéric</p>
</div>
<div class="swiper-slide comment">
<p class="comment__text">
<p class="comment-text">
Merci de poursuivre cette quête inlassable pour révéler les
vérités que l'on nous tait.
</p>
<p class="comment__name">Pauline</p>
<p class="comment-name">Pauline</p>
</div>
<div class="swiper-slide comment">
<p class="comment__text">
<p class="comment-text">
Les enquêteurs d'Index font un travail essentiel pour la
démocratie et la justice. Par ce soutien citoyen, j'exprime
toute ma reconnaissance pour leur engagement et leur rigueur.
</p>
<p class="comment__name">Anne</p>
<p class="comment-name">Anne</p>
</div>
</div>
<div class="swiper-pagination comments-slider__dots"></div>
<div class="swiper-pagination comments-dots"></div>
</div>
</section>
</div>
<div id="btn--don__mobile">
<button class="btn--don">
<a href="#section__donation">
<div id="donation-cta-mobile">
<a href="#section__donation" class="donation-cta" role="button">
<span class="txt">Faire un don</span>
<span class="icon">
<svg
@ -738,21 +737,20 @@
/>
</svg>
</span>
</a>
</button>
</a>
</div>
</main>
<footer id="site-footer">
<div class="site-footer__container">
<div class="footer__newsletter">
<div class="footer-container">
<div class="footer-newsletter">
<p>
Recevez les dernières enquêtes et actualités dIndex directement
dans votre boîte mail.
</p>
<p>Inscrivez-vous à la newsletter</p>
<form class="form__newsletter">
<form class="newsletter-form">
<input
type="email"
name="email"
@ -779,7 +777,7 @@
</button>
</form>
<p class="p__small">
<p class="text-small">
En vous inscrivant, vous acceptez les
<a target="_blank" href="https://www.index.ngo/mentions-legales/"
>conditions dutilisation</a
@ -789,10 +787,10 @@
</p>
</div>
<div class="footer__socials">
<div class="footer-socials">
<p>Suivez Index sur les réseaux sociaux</p>
<ul id="list-socials">
<ul id="socials-list">
<li>
<a
href="https://www.youtube.com/index-ngo"
@ -973,8 +971,8 @@
</ul>
</div>
<div class="footer__mentions">
<p class="p__small">
<div class="footer-mentions">
<p class="text-small">
© 2025 Index Investigation |
<a target="_blank" href="https://www.index.ngo/mentions-legales/"
>Mentions légales</a
@ -993,7 +991,7 @@
disableOnInteraction: false, // continue après un swipe
},
pagination: {
el: '.comments-slider__dots',
el: '.comments-dots',
clickable: true,
},
});

270
index.php Normal file
View file

@ -0,0 +1,270 @@
<?php
require_once __DIR__ . '/includes/cache.php';
$data = getSoutenirContent('fr');
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><?= htmlspecialchars($data['metaTitle'] ?? 'Soutenir Index') ?></title>
<meta name="description" content="<?= htmlspecialchars($data['metaDescription'] ?? '') ?>" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.css" />
<script src="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.js"></script>
<link rel="icon" type="image/png" href="assets/favicon.png" />
<link rel="stylesheet" type="text/css" href="assets/fonts/stylesheet.css" />
<link rel="stylesheet" type="text/css" href="assets/css/style.css" />
<script src="assets/js/onload.js"></script>
<script src="assets/js/temp/includeHtml.js"></script>
<script src="assets/js/donorbox-gauge.js"></script>
<script src="assets/js/donation.js"></script>
<script src="assets/js/newsletter-brevo.js"></script>
<meta name="robots" content="index, nofollow" />
</head>
<body data-template="support">
<header id="site-header">
<div class="header-left"></div>
<div class="header-center">
<h1 class="site-title">
<a href="https://www.index.ngo/" aria-label="Retour à l'accueil" title="aller au site d'Index">
<svg width="100%" height="100%" viewBox="0 0 162 29" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<title>Index.ngo</title>
<g transform="matrix(1.04516,0,0,0.659091,57.4839,-6.59091)">
<rect x="-55" y="10" width="155" height="44" style="fill:none"/>
<clipPath id="_clip1"><rect x="-55" y="10" width="155" height="44"/></clipPath>
<g clip-path="url(#_clip1)">
<g transform="matrix(0.95679,0,0,1.51724,-55,10)">
<path d="M162,29L148.198,29L141.174,20.767L134.15,29L91.184,29L91.184,0.004L120.653,0.004L120.653,7.351L102.637,7.351L102.637,10.867L120.137,10.867L120.137,18.13L102.637,18.13L102.637,21.606L120.926,21.606L120.926,28.951L134.273,14.414L120.807,0L134.56,0L141.388,7.767L147.76,0L161.201,0L148.236,13.79L161.996,28.997L162,29ZM68.58,29L54.224,29L54.224,0.004L68.637,0.004C74.672,0.004 78.31,0.004 82.046,2.045C86.259,4.379 88.674,8.889 88.674,14.417C88.674,19.406 86.862,23.405 83.427,25.975C79.463,29 75.345,29 68.58,29ZM49.819,29L38.775,29L31.499,19.815C29.746,17.735 28.088,15.545 27.307,14.495C27.387,15.813 27.524,17.238 27.524,20.499L27.524,29L15.965,29L15.965,0.004L27.009,0.004L33.798,8.349C36.223,11.121 37.709,12.993 38.393,13.881C38.347,12.615 38.26,9.911 38.26,6.84L38.26,0.004L49.819,0.004L49.819,29ZM11.559,29L0,29L0,0.004L11.559,0.004L11.559,29ZM65.784,21.818L67.904,21.818C70.918,21.818 73.067,21.818 74.728,20.531C76.074,19.491 76.845,17.308 76.845,14.541C76.845,11.526 76.084,9.541 74.525,8.476C72.895,7.411 71.461,7.224 67.578,7.224L65.784,7.224L65.784,21.818Z" style="fill-rule:nonzero"/>
</g>
</g>
</g>
</svg>
</a>
</h1>
</div>
<div class="header-right">
<ul id="toggle-lang">
<li class="is-selected"><a href="./">Fr</a></li>
<li><a href="./en">En</a></li>
</ul>
</div>
</header>
<main>
<div class="col-left">
<section id="section__hero">
<p class="hero-heading"><?= $data['heroHeading'] ?? '' ?></p>
<div class="gauge-container">
<div id="gauge" style="--pourcent: 0%"></div>
<div class="gauge-info" id="gauge-info--supporters">
<p class="property">Soutiens réguliers</p>
<p class="value">0</p>
</div>
<div class="gauge-info" id="gauge-info--goal">
<p class="property">Objectif</p>
<p class="value">500</p>
</div>
</div>
<p class="hero-heading">
<?= htmlspecialchars($data['heroObjectiveLabel'] ?? '') ?><br />
<strong><?= htmlspecialchars($data['heroObjectiveDate'] ?? '') ?></strong>
</p>
</section>
<section id="section__baseline">
<p class="subheading"><?= $data['subheading'] ?? '' ?></p>
</section>
<section id="section__video">
<h2 class="section-heading"><?= $data['videoSectionHeading'] ?? '' ?></h2>
<div class="video-container">
<iframe
title="Vidéo de campagne"
src="<?= htmlspecialchars($data['mainVideoUrl'] ?? '') ?>"
style="aspect-ratio: 9/16; width: 100%; border: 0"
allow="autoplay; fullscreen; picture-in-picture"
allowfullscreen
></iframe>
</div>
<?php if (!empty($data['testimonies'])): ?>
<input type="checkbox" id="testimonies-toggle" />
<label class="btn-expand" for="testimonies-toggle">
<span class="txt"><?= htmlspecialchars($data['testimoniesButtonLabel'] ?? 'Voir les témoignages') ?></span>
<span class="icon"><svg width="34px" height="34px" viewBox="0 0 16 13" version="1.1" xmlns="http://www.w3.org/2000/svg" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<rect x="0" y="0" width="15.43" height="12.636" style="fill:none"/>
<path d="M0,7.29L0,5.373L9.801,5.373C10.67,5.373 11.757,5.4 12.387,5.427C11.952,5.022 11.366,4.455 10.888,3.969L8.432,1.404L9.366,0L15.43,6.318L9.366,12.636L8.432,11.232L10.888,8.667C11.366,8.181 11.952,7.614 12.387,7.236C11.757,7.263 10.67,7.29 9.801,7.29L0,7.29Z" style="fill-rule:nonzero"/>
</svg></span>
</label>
<ul class="testimonies-list">
<?php foreach ($data['testimonies'] as $testimony): ?>
<li class="testimony-item" data-video="<?= htmlspecialchars($testimony['videoUrl']) ?>">
<span class="icon">
<svg height="80px" width="80px" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
<path d="M500.203,236.907L30.869,2.24c-6.613-3.285-14.443-2.944-20.736,0.939C3.84,7.083,0,13.931,0,21.333v469.333 c0,7.403,3.84,14.251,10.133,18.155c3.413,2.112,7.296,3.179,11.2,3.179c3.264,0,6.528-0.747,9.536-2.24l469.333-234.667 C507.435,271.467,512,264.085,512,256S507.435,240.533,500.203,236.907z"/>
</svg>
</span>
<p class="txt"><?= $testimony['description'] ?></p>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</section>
<section id="section__questions">
<h2 class="section-heading"><?= htmlspecialchars($data['faqHeading'] ?? 'Questions fréquentes') ?></h2>
<?php foreach (($data['questions'] ?? []) as $q): ?>
<details>
<summary><?= htmlspecialchars($q['question']) ?></summary>
<?= $q['answer'] ?>
</details>
<?php endforeach; ?>
</section>
</div>
<div class="col-right">
<section id="section__donation">
<nav class="nav--tabs">
<button class="nav--tabs__btn is-selected">Je donne tous les mois</button>
<button class="nav--tabs__btn">Je donne une fois</button>
</nav>
<div data-donation="one-off" class="donation-grid">
<button class="donation-btn">
<p class="bold">200&#8239;€</p>
<p class="small">Soit 68&#8239;€ après impôts</p>
</button>
<button class="donation-btn donation-btn--wide">
<p class="bold">100&#8239;€</p>
<p class="small">Soit 34&#8239;€ après impôts</p>
</button>
<button class="donation-btn donation-btn--wide">
<p class="bold">50&#8239;€</p>
<p class="small">Soit 17&#8239;€ après impôts</p>
</button>
<button class="donation-btn donation-btn--wide">
<p class="bold">20&#8239;€</p>
<p class="small">Soit 6.80&#8239;€ après impôts</p>
</button>
<button class="donation-btn donation-btn--full">
<p class="bold">Choisissez votre montant</p>
<p class="small">Avec déduction fiscale de 66&#8239;%</p>
</button>
</div>
<div data-donation="monthly" class="donation-grid is-selected">
<button class="donation-btn">
<p class="bold">5/mois</p>
<p class="small">Soit X€ après impôts</p>
</button>
<button class="donation-btn donation-btn--wide">
<p class="bold">10/mois</p>
<p class="small">Soit X€ après impôts</p>
</button>
<button class="donation-btn donation-btn--wide">
<p class="bold">20/mois</p>
<p class="small">Soit X€ après impôts</p>
</button>
<button class="donation-btn donation-btn--wide">
<p class="bold">50/mois</p>
<p class="small">Soit X€ après impôts</p>
</button>
<button class="donation-btn donation-btn--full">
<p class="bold">Choisissez votre montant</p>
<p class="small">Avec déduction fiscale</p>
</button>
</div>
</section>
<section id="section__comments">
<h2 class="section-heading"><?= htmlspecialchars($data['commentsHeading'] ?? 'Commentaires de donateur·ices') ?></h2>
<div class="swiper" id="comments-slider">
<div class="swiper-wrapper">
<?php foreach (($data['comments'] ?? []) as $comment): ?>
<div class="swiper-slide">
<p class="comment-text"><?= htmlspecialchars($comment['text']) ?></p>
<p class="comment-name"><?= htmlspecialchars($comment['name']) ?></p>
</div>
<?php endforeach; ?>
</div>
<div class="swiper-pagination comments-dots"></div>
</div>
</section>
</div>
<div id="donation-cta-mobile">
<a href="#section__donation" class="donation-cta" role="button">
<span class="txt">Faire un don</span>
<span class="icon">
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m14.523 18.787s4.501-4.505 6.255-6.26c.146-.146.219-.338.219-.53s-.073-.383-.219-.53c-1.753-1.754-6.255-6.258-6.255-6.258-.144-.145-.334-.217-.524-.217-.193 0-.385.074-.532.221-.293.292-.295.766-.004 1.056l4.978 4.978h-14.692c-.414 0-.75.336-.75.75s.336.75.75.75h14.692l-4.979 4.979c-.289.289-.286.762.006 1.054.148.148.341.222.533.222.19 0 .378-.072.522-.215z" fill-rule="nonzero"/>
</svg>
</span>
</a>
</div>
</main>
<footer id="site-footer">
<div class="footer-container">
<div class="footer-newsletter">
<p><?= $data['footerNewsletterText'] ?? '' ?></p>
<form class="newsletter-form">
<input type="email" name="email" placeholder="Votre adresse e-mail" required />
<button class="btn--bold" type="submit" aria-label="s'inscrire">
<span class="txt"><?= htmlspecialchars($data['footerNewsletterCta'] ?? "S'inscrire") ?></span>
<span class="icon">
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m14.523 18.787s4.501-4.505 6.255-6.26c.146-.146.219-.338.219-.53s-.073-.383-.219-.53c-1.753-1.754-6.255-6.258-6.255-6.258-.144-.145-.334-.217-.524-.217-.193 0-.385.074-.532.221-.293.292-.295.766-.004 1.056l4.978 4.978h-14.692c-.414 0-.75.336-.75.75s.336.75.75.75h14.692l-4.979 4.979c-.289.289-.286.762.006 1.054.148.148.341.222.533.222.19 0 .378-.072.522-.215z" fill-rule="nonzero"/>
</svg>
</span>
</button>
</form>
<p class="text-small"><?= $data['footerNewsletterDisclaimer'] ?? '' ?></p>
</div>
<div class="footer-socials">
<p><?= htmlspecialchars($data['footerSocialsHeading'] ?? '') ?></p>
<ul id="socials-list">
<?php foreach (($data['footerSocials'] ?? []) as $social): ?>
<li>
<a href="<?= htmlspecialchars($social['url']) ?>" target="_blank" rel="noopener noreferrer">
<span class="icon"><?= $social['svgIcon'] ?></span>
<span class="text"><?= htmlspecialchars($social['name']) ?></span>
</a>
</li>
<?php endforeach; ?>
</ul>
</div>
<div class="footer-mentions">
<p class="text-small"><?= $data['footerMentions'] ?? '' ?></p>
</div>
</div>
</footer>
<script>
const swiper = new Swiper('#comments-slider', {
slidesPerView: 1,
loop: true,
autoplay: {
delay: 4000,
disableOnInteraction: false,
},
pagination: {
el: '.comments-dots',
clickable: true,
},
});
</script>
</body>
</html>

View file

@ -78,27 +78,27 @@
</header>
<main>
<p class="p__baseline-big">
<p class="hero-heading">
Un grand merci&#8239;!
</p>
<p class="p__baseline">
<p class="subheading">
Votre soutien nous permet de continuer à enquêter en toute indépendance.</p>
<p class="p__baseline"> Nous vous remercions sincèrement pour votre solidarité, qui est essentielle à&nbsp;la&nbsp;poursuite de notre mission.</p>
<p class="subheading"> Nous vous remercions sincèrement pour votre solidarité, qui est essentielle à&nbsp;la&nbsp;poursuite de notre mission.</p>
<p class="p__baseline"><a href="https://www.index.ngo/" class="link-don">Retour à la page daccueil →</a></p>
<p class="subheading"><a href="https://www.index.ngo/" class="link-don">Retour à la page daccueil →</a></p>
</p>
</main>
<footer id="site-footer">
<div class="site-footer__container">
<div class="footer-container">
<div class="footer__mentions">
<p class="p__small">
<div class="footer-mentions">
<p class="text-small">
© 2025 Index Investigation | <a target="_blank" href="https://www.index.ngo/mentions-legales/">Mentions légales</a>
</p>
</div>

63
merci/index.php Normal file
View file

@ -0,0 +1,63 @@
<?php
require_once __DIR__ . '/../includes/cache.php';
$data = getSoutenirContent('fr');
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Index.ngo</title>
<link rel="icon" type="image/png" href="/assets/favicon.png" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.css" />
<script src="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.js"></script>
<link rel="stylesheet" type="text/css" href="/assets/fonts/stylesheet.css" />
<link rel="stylesheet" type="text/css" href="/assets/css/style.css" />
<script src="/assets/js/onload.js"></script>
<script src="/assets/js/temp/includeHtml.js"></script>
<script src="/assets/js/newsletter-brevo.js"></script>
</head>
<body data-template="thanks">
<header id="site-header">
<div class="header-left"></div>
<div class="header-center">
<h1 class="site-title">
<a href="/" aria-label="Retour à l'accueil">
<svg width="100%" height="100%" viewBox="0 0 162 29" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<title>Index.ngo</title>
<g transform="matrix(1.04516,0,0,0.659091,57.4839,-6.59091)">
<rect x="-55" y="10" width="155" height="44" style="fill:none"/>
<clipPath id="_clip1"><rect x="-55" y="10" width="155" height="44"/></clipPath>
<g clip-path="url(#_clip1)">
<g transform="matrix(0.95679,0,0,1.51724,-55,10)">
<path d="M162,29L148.198,29L141.174,20.767L134.15,29L91.184,29L91.184,0.004L120.653,0.004L120.653,7.351L102.637,7.351L102.637,10.867L120.137,10.867L120.137,18.13L102.637,18.13L102.637,21.606L120.926,21.606L120.926,28.951L134.273,14.414L120.807,0L134.56,0L141.388,7.767L147.76,0L161.201,0L148.236,13.79L161.996,28.997L162,29ZM68.58,29L54.224,29L54.224,0.004L68.637,0.004C74.672,0.004 78.31,0.004 82.046,2.045C86.259,4.379 88.674,8.889 88.674,14.417C88.674,19.406 86.862,23.405 83.427,25.975C79.463,29 75.345,29 68.58,29ZM49.819,29L38.775,29L31.499,19.815C29.746,17.735 28.088,15.545 27.307,14.495C27.387,15.813 27.524,17.238 27.524,20.499L27.524,29L15.965,29L15.965,0.004L27.009,0.004L33.798,8.349C36.223,11.121 37.709,12.993 38.393,13.881C38.347,12.615 38.26,9.911 38.26,6.84L38.26,0.004L49.819,0.004L49.819,29ZM11.559,29L0,29L0,0.004L11.559,0.004L11.559,29ZM65.784,21.818L67.904,21.818C70.918,21.818 73.067,21.818 74.728,20.531C76.074,19.491 76.845,17.308 76.845,14.541C76.845,11.526 76.084,9.541 74.525,8.476C72.895,7.411 71.461,7.224 67.578,7.224L65.784,7.224L65.784,21.818Z" style="fill-rule:nonzero"/>
</g>
</g>
</g>
</svg>
</a>
</h1>
</div>
<div class="header-right"></div>
</header>
<main>
<p class="hero-heading"><?= htmlspecialchars($data['thanksHeading'] ?? 'Un grand merci !') ?></p>
<?= $data['thanksText'] ?? '' ?>
<p class="subheading"><a href="<?= htmlspecialchars($data['thanksLinkUrl'] ?? 'https://www.index.ngo/') ?>" class="link-don"><?= htmlspecialchars($data['thanksLinkText'] ?? "Retour à la page d'accueil →") ?></a></p>
</main>
<footer id="site-footer">
<div class="footer-container">
<div class="footer-mentions">
<p class="text-small"><?= $data['thanksMentions'] ?? '' ?></p>
</div>
</div>
</footer>
</body>
</html>

View file

@ -78,27 +78,27 @@
</header>
<main>
<p class="p__baseline-big">
<p class="hero-heading">
Thank you!
</p>
<p class="p__baseline">
<p class="subheading">
Your support allows us to continue investigating with complete independence.</p>
<p class="p__baseline">We sincerely thank you for your solidarity, which is essential to the pursuit of our&nbsp;mission.</p>
<p class="subheading">We sincerely thank you for your solidarity, which is essential to the pursuit of our&nbsp;mission.</p>
<p class="p__baseline"><a href="https://www.index.ngo/en/">Back to home page →</a></p>
<p class="subheading"><a href="https://www.index.ngo/en/">Back to home page →</a></p>
</p>
</main>
<footer id="site-footer">
<div class="site-footer__container">
<div class="footer-container">
<div class="footer__mentions">
<p class="p__small">
<div class="footer-mentions">
<p class="text-small">
© 2025 Index Investigation | <a target="_blank" href="https://www.index.ngo/mentions-legales/">Mentions légales</a>
</p>
</div>

63
thanks/index.php Normal file
View file

@ -0,0 +1,63 @@
<?php
require_once __DIR__ . '/../includes/cache.php';
$data = getSoutenirContent('en');
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Index.ngo</title>
<link rel="icon" type="image/png" href="/assets/favicon.png" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.css" />
<script src="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.js"></script>
<link rel="stylesheet" type="text/css" href="/assets/fonts/stylesheet.css" />
<link rel="stylesheet" type="text/css" href="/assets/css/style.css" />
<script src="/assets/js/onload.js"></script>
<script src="/assets/js/temp/includeHtml.js"></script>
<script src="/assets/js/newsletter-brevo.js"></script>
</head>
<body data-template="thanks">
<header id="site-header">
<div class="header-left"></div>
<div class="header-center">
<h1 class="site-title">
<a href="/" aria-label="Back to home">
<svg width="100%" height="100%" viewBox="0 0 162 29" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<title>Index.ngo</title>
<g transform="matrix(1.04516,0,0,0.659091,57.4839,-6.59091)">
<rect x="-55" y="10" width="155" height="44" style="fill:none"/>
<clipPath id="_clip1"><rect x="-55" y="10" width="155" height="44"/></clipPath>
<g clip-path="url(#_clip1)">
<g transform="matrix(0.95679,0,0,1.51724,-55,10)">
<path d="M162,29L148.198,29L141.174,20.767L134.15,29L91.184,29L91.184,0.004L120.653,0.004L120.653,7.351L102.637,7.351L102.637,10.867L120.137,10.867L120.137,18.13L102.637,18.13L102.637,21.606L120.926,21.606L120.926,28.951L134.273,14.414L120.807,0L134.56,0L141.388,7.767L147.76,0L161.201,0L148.236,13.79L161.996,28.997L162,29ZM68.58,29L54.224,29L54.224,0.004L68.637,0.004C74.672,0.004 78.31,0.004 82.046,2.045C86.259,4.379 88.674,8.889 88.674,14.417C88.674,19.406 86.862,23.405 83.427,25.975C79.463,29 75.345,29 68.58,29ZM49.819,29L38.775,29L31.499,19.815C29.746,17.735 28.088,15.545 27.307,14.495C27.387,15.813 27.524,17.238 27.524,20.499L27.524,29L15.965,29L15.965,0.004L27.009,0.004L33.798,8.349C36.223,11.121 37.709,12.993 38.393,13.881C38.347,12.615 38.26,9.911 38.26,6.84L38.26,0.004L49.819,0.004L49.819,29ZM11.559,29L0,29L0,0.004L11.559,0.004L11.559,29ZM65.784,21.818L67.904,21.818C70.918,21.818 73.067,21.818 74.728,20.531C76.074,19.491 76.845,17.308 76.845,14.541C76.845,11.526 76.084,9.541 74.525,8.476C72.895,7.411 71.461,7.224 67.578,7.224L65.784,7.224L65.784,21.818Z" style="fill-rule:nonzero"/>
</g>
</g>
</g>
</svg>
</a>
</h1>
</div>
<div class="header-right"></div>
</header>
<main>
<p class="hero-heading"><?= htmlspecialchars($data['thanksHeading'] ?? 'Thank you!') ?></p>
<?= $data['thanksText'] ?? '' ?>
<p class="subheading"><a href="<?= htmlspecialchars($data['thanksLinkUrl'] ?? 'https://www.index.ngo/en/') ?>"><?= htmlspecialchars($data['thanksLinkText'] ?? 'Back to home page →') ?></a></p>
</main>
<footer id="site-footer">
<div class="footer-container">
<div class="footer-mentions">
<p class="text-small"><?= $data['thanksMentions'] ?? '' ?></p>
</div>
</div>
</footer>
</body>
</html>