Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions content/en/donate-2026.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: Support Let's Encrypt
slug: donate-2026
type: page
layout: donate-2026
no_donate_footer: true
useContainer: false
lastmod: 2026-06-05
---
37 changes: 37 additions & 0 deletions data/donate-2026.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"items": [
{
"id": "item-1",
"eyebrow": "Donate $40+ [PLACEHOLDER]",
"title": "Item One [PLACEHOLDER]",
"description": "Replace this description with the actual merch item details.",
"images": [
{ "thumb": "/images/donate-2024/thumbs/Thumbnail-Donate-2024-Gift-Puzzle-1.png", "full": "/images/donate-2024/Selections/Puzzle/Donate-2024-Gift-Puzzle-1.png" },
{ "thumb": "/images/donate-2024/thumbs/Thumbnail-Donate-2024-Gift-Puzzle-2.jpg", "full": "/images/donate-2024/Selections/Puzzle/Donate-2024-Gift-Puzzle-2.png" },
{ "thumb": "/images/donate-2024/thumbs/Thumbnail-Donate-2024-Gift-Puzzle-3.png", "full": "/images/donate-2024/Selections/Puzzle/Donate-2024-Gift-Puzzle-3.png" }
]
},
{
"id": "item-2",
"eyebrow": "Donate $40+ [PLACEHOLDER]",
"title": "Item Two [PLACEHOLDER]",
"description": "Replace this description with the actual merch item details.",
"images": [
{ "thumb": "/images/donate-2024/thumbs/Thumbnail-Donate-2024-Gift-Print-1.jpg", "full": "/images/donate-2024/Selections/Poster/Donate-2024-Gift-Print-1.png" },
{ "thumb": "/images/donate-2024/thumbs/Thumbnail-Donate-2024-Gift-Print-2.jpg", "full": "/images/donate-2024/Selections/Poster/Donate-2024-Gift-Print-2.png" },
{ "thumb": "/images/donate-2024/thumbs/Thumbnail-Donate-2024-Gift-Print-3.jpg", "full": "/images/donate-2024/Selections/Poster/Donate-2024-Gift-Print-3.png" }
]
},
{
"id": "item-3",
"eyebrow": "Donate $40+ [PLACEHOLDER]",
"title": "Item Three [PLACEHOLDER]",
"description": "Replace this description with the actual merch item details.",
"images": [
{ "thumb": "/images/donate-2024/thumbs/Thumbnail-Donate-2024-Gift-Shirt-1.jpg", "full": "/images/donate-2024/Selections/Tee/Donate-2024-Gift-Shirt-1.png" },
{ "thumb": "/images/donate-2024/thumbs/Thumbnail-Donate-2024-Gift-Shirt-2.jpg", "full": "/images/donate-2024/Selections/Tee/Donate-2024-Gift-Shirt-2.png" },
{ "thumb": "/images/donate-2024/thumbs/Thumbnail-Donate-2024-Gift-Shirt-3.jpg", "full": "/images/donate-2024/Selections/Tee/Donate-2024-Gift-Shirt-3.png" }
]
}
]
}
11 changes: 11 additions & 0 deletions i18n/en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -549,3 +549,14 @@ other = "We are able to accept most cryptocurrency donations {{ .cryptoLink }}."

[donate_page_crypto_link_text]
other = "here"

# ── Donate 2026 Campaign ──────────────────────────────────

[donate_2026_hero_title]
other = "Encryption for Everybody."

[donate_2026_hero_body]
other = "For over a decade, Let's Encrypt has provided billions of free TLS certificates. Each one made possible thanks to the generosity of people like you. Donate today to help us continue this work, and we'll say thanks with a gift of your choosing."

[donate_2026_cta_button]
other = "Donate Now"
43 changes: 43 additions & 0 deletions themes/le-2025/assets/css/donate-2026.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* ── Donate 2026 Campaign ──────────────────────────────── */
@utility donate-2026-item {
@apply flex flex-col md:flex-row gap-6 pb-10 border-b border-gray-200;

&:last-child {
@apply border-b-0;
}
}
@utility donate-2026-carousel {
@apply w-full md:w-48 flex-shrink-0;
}
@utility donate-2026-carousel-img {
@apply hidden w-full rounded-lg bg-white object-contain cursor-zoom-in;

&.active {
@apply block;
}
}
@utility donate-2026-carousel-prev {
@apply w-8 h-8 bg-gray-200 rounded text-center font-bold text-base leading-8 hover:bg-gray-300 select-none;
}
@utility donate-2026-carousel-next {
@apply w-8 h-8 bg-gray-200 rounded text-center font-bold text-base leading-8 hover:bg-gray-300 select-none;
}
@utility donate-2026-eyebrow {
@apply uppercase tracking-wider text-sm font-bold text-le-yellow mb-2;
}
@utility donate-2026-lightbox {
@apply hidden fixed inset-0 z-[999] bg-black/70 items-center justify-center;

&.active {
@apply flex;
}
}
@utility donate-2026-sticky-cta {
@apply fixed bottom-0 left-0 w-full z-[1000] lg:hidden;
transform: translateY(100%);
transition: transform 0.2s ease-in-out;

&.visible {
transform: translateY(0);
}
}
2 changes: 2 additions & 0 deletions themes/le-2025/assets/css/le-2025-theme-input.css
Original file line number Diff line number Diff line change
Expand Up @@ -673,3 +673,5 @@
.prose-content .pull-quote-right blockquote {
@apply mt-0 pt-0 border-0 pl-0;
}

@import "./donate-2026.css";
97 changes: 97 additions & 0 deletions themes/le-2025/assets/js/donate-2026.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
const Donate2026 = {
init() {
const page = document.getElementById('donate-2026-page');
if (!page) return;

this.initCarousels();
this.initLightbox();
this.initStickyCTA();
},

initCarousels() {
document.querySelectorAll('.donate-2026-carousel').forEach(carousel => {
const images = carousel.querySelectorAll('.donate-2026-carousel-img');
const prevBtn = carousel.querySelector('.donate-2026-carousel-prev');
const nextBtn = carousel.querySelector('.donate-2026-carousel-next');
const counter = carousel.querySelector('.donate-2026-carousel-counter');
if (images.length <= 1) return;

let current = 0;

const show = (index) => {
images[current].classList.remove('active');
current = (index + images.length) % images.length;
images[current].classList.add('active');
if (counter) counter.textContent = `${current + 1} / ${images.length}`;
};

prevBtn.addEventListener('click', () => show(current - 1));
nextBtn.addEventListener('click', () => show(current + 1));

images.forEach(img => {
img.addEventListener('click', () => {
const fullSrc = img.getAttribute('data-full');
if (fullSrc) this.openLightbox(fullSrc);
});
});
});
},

initLightbox() {
const lightbox = document.getElementById('donate-2026-lightbox');
const lightboxImg = document.getElementById('donate-2026-lightbox-img');
if (!lightbox || !lightboxImg) return;

lightbox.addEventListener('click', (e) => {
if (e.target === lightboxImg) return;
this.closeLightbox();
});

document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && lightbox.getAttribute('aria-hidden') === 'false') {
this.closeLightbox();
}
});
},

openLightbox(src) {
const lightbox = document.getElementById('donate-2026-lightbox');
const lightboxImg = document.getElementById('donate-2026-lightbox-img');
lightboxImg.src = src;
lightbox.setAttribute('aria-hidden', 'false');
lightbox.classList.add('active');
document.body.style.overflow = 'hidden';
},

closeLightbox() {
const lightbox = document.getElementById('donate-2026-lightbox');
lightbox.setAttribute('aria-hidden', 'true');
lightbox.classList.remove('active');
document.body.style.overflow = '';
},

initStickyCTA() {
const cta = document.getElementById('donate-2026-sticky-cta');
const anchor = document.getElementById('donate-2026-form-anchor');
if (!cta || !anchor) return;

const update = () => {
const rect = anchor.getBoundingClientRect();
const formVisible = rect.top >= -100 && rect.top <= window.innerHeight + 100;
cta.classList.toggle('visible', !formVisible);
};

cta.querySelector('a').addEventListener('click', (e) => {
e.preventDefault();
anchor.scrollIntoView({ behavior: 'smooth' });
});

document.addEventListener('scroll', update, { passive: true });
window.addEventListener('resize', update);
update();
}
};

document.addEventListener('DOMContentLoaded', () => {
Donate2026.init();
});
48 changes: 48 additions & 0 deletions themes/le-2025/layouts/page/donate-2026.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{{ define "main" }}
<div id="donate-2026-page">
{{ partial "donate-2026/campaign-hero.html" . }}

<div class="container mx-auto py-8">
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<div class="lg:col-span-2 space-y-10">
{{ range (index site.Data "donate-2026").items }}
{{ partial "donate-2026/campaign-item.html" . }}
{{ end }}
</div>

<div class="relative">
<div id="donate-2026-form-anchor"></div>
<div class="lg:sticky lg:top-4">
{{ partial "donorbox.html" $ }}
</div>
</div>
</div>
</div>

{{/* ── Lightbox overlay ───────────────────────────────── */}}
<div id="donate-2026-lightbox" class="donate-2026-lightbox" aria-hidden="true" role="dialog" aria-label="Enlarged image">
<button type="button" class="absolute top-4 right-6 text-white text-4xl font-bold hover:text-gray-300 z-10" aria-label="Close">&times;</button>
<img alt="Full size image" class="max-w-full max-h-full object-contain m-auto" id="donate-2026-lightbox-img" />
</div>

{{/* ── Mobile sticky CTA ──────────────────────────────── */}}
<div id="donate-2026-sticky-cta" class="donate-2026-sticky-cta">
<a href="#donate-2026-form-anchor" class="block w-full text-center py-3 bg-le-yellow text-le-blue font-bold text-lg no-underline hover:bg-le-yellow/90">
{{ T "donate_2026_cta_button" }}
</a>
</div>
</div>

{{ with resources.Get "js/donate-2026.js" }}
{{ if eq hugo.Environment "development" }}
{{ with . | js.Build }}
<script src="{{ .RelPermalink }}"></script>
{{ end }}
{{ else }}
{{ $opts := dict "minify" true }}
{{ with . | js.Build $opts | fingerprint }}
<script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script>
{{ end }}
{{ end }}
{{ end }}
{{ end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<section class="bg-le-blue text-white py-16">
<div class="container mx-auto">
<h1 class="text-hero-heading text-white mb-6">{{ T "donate_2026_hero_title" }}</h1>
<p class="text-lg max-w-2xl">{{ T "donate_2026_hero_body" }}</p>
</div>
</section>
25 changes: 25 additions & 0 deletions themes/le-2025/layouts/partials/donate-2026/campaign-item.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{{- $id := .id -}}
<div class="donate-2026-item" id="campaign-item-{{ $id }}">
<div class="donate-2026-carousel" aria-label="{{ .title }} images">
{{- range $i, $img := .images }}
<img
src="{{ $img.thumb }}"
data-full="{{ $img.full }}"
alt="{{ $.title }}{{ if gt (len $.images) 1 }} — image {{ add $i 1 }} of {{ len $.images }}{{ end }}"
class="donate-2026-carousel-img{{ if eq $i 0 }} active{{ end }}"
/>
{{- end }}
{{ if gt (len .images) 1 }}
<div class="flex items-center justify-center gap-2 mt-3">
<button type="button" class="donate-2026-carousel-prev" aria-label="Previous image">&#10094;</button>
<span class="donate-2026-carousel-counter text-sm text-gray-500" aria-live="polite">1 / {{ len .images }}</span>
<button type="button" class="donate-2026-carousel-next" aria-label="Next image">&#10095;</button>
</div>
{{ end }}
</div>
<div class="donate-2026-item-text">
<div class="donate-2026-eyebrow">{{ .eyebrow }}</div>
<h2 class="text-2xl font-bold text-le-blue mb-3">{{ .title }}</h2>
<p class="text-base text-gray-700">{{ .description }}</p>
</div>
</div>
Loading