From 8a8d62c22dd28a4174f2512a194c3430ff91c2c7 Mon Sep 17 00:00:00 2001 From: scottmakestech <83726258+scottmakestech@users.noreply.github.com> Date: Fri, 5 Jun 2026 11:29:08 -0500 Subject: [PATCH] Prepare 2026 Donation Campaign page --- content/en/donate-2026.html | 9 ++ data/donate-2026.json | 37 +++++++ i18n/en.toml | 11 +++ themes/le-2025/assets/css/donate-2026.css | 43 ++++++++ .../assets/css/le-2025-theme-input.css | 2 + themes/le-2025/assets/js/donate-2026.js | 97 +++++++++++++++++++ themes/le-2025/layouts/page/donate-2026.html | 48 +++++++++ .../partials/donate-2026/campaign-hero.html | 6 ++ .../partials/donate-2026/campaign-item.html | 25 +++++ 9 files changed, 278 insertions(+) create mode 100644 content/en/donate-2026.html create mode 100644 data/donate-2026.json create mode 100644 themes/le-2025/assets/css/donate-2026.css create mode 100644 themes/le-2025/assets/js/donate-2026.js create mode 100644 themes/le-2025/layouts/page/donate-2026.html create mode 100644 themes/le-2025/layouts/partials/donate-2026/campaign-hero.html create mode 100644 themes/le-2025/layouts/partials/donate-2026/campaign-item.html diff --git a/content/en/donate-2026.html b/content/en/donate-2026.html new file mode 100644 index 000000000..f3e684815 --- /dev/null +++ b/content/en/donate-2026.html @@ -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 +--- diff --git a/data/donate-2026.json b/data/donate-2026.json new file mode 100644 index 000000000..2c96b8f8c --- /dev/null +++ b/data/donate-2026.json @@ -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" } + ] + } + ] +} diff --git a/i18n/en.toml b/i18n/en.toml index 3ada28eb5..f4f6f2153 100644 --- a/i18n/en.toml +++ b/i18n/en.toml @@ -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" diff --git a/themes/le-2025/assets/css/donate-2026.css b/themes/le-2025/assets/css/donate-2026.css new file mode 100644 index 000000000..6728b54b2 --- /dev/null +++ b/themes/le-2025/assets/css/donate-2026.css @@ -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); + } +} diff --git a/themes/le-2025/assets/css/le-2025-theme-input.css b/themes/le-2025/assets/css/le-2025-theme-input.css index f5384b05b..32e15b8e5 100644 --- a/themes/le-2025/assets/css/le-2025-theme-input.css +++ b/themes/le-2025/assets/css/le-2025-theme-input.css @@ -673,3 +673,5 @@ .prose-content .pull-quote-right blockquote { @apply mt-0 pt-0 border-0 pl-0; } + +@import "./donate-2026.css"; diff --git a/themes/le-2025/assets/js/donate-2026.js b/themes/le-2025/assets/js/donate-2026.js new file mode 100644 index 000000000..00e5ed2aa --- /dev/null +++ b/themes/le-2025/assets/js/donate-2026.js @@ -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(); +}); diff --git a/themes/le-2025/layouts/page/donate-2026.html b/themes/le-2025/layouts/page/donate-2026.html new file mode 100644 index 000000000..e63c71326 --- /dev/null +++ b/themes/le-2025/layouts/page/donate-2026.html @@ -0,0 +1,48 @@ +{{ define "main" }} +
{{ T "donate_2026_hero_body" }}
+{{ .description }}
+