From ecf2091b62fd2d563db35a3d8c3ca26a23bce14e Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Tue, 15 Sep 2026 17:17:58 -0600 Subject: [PATCH 01/11] heroes: extract shared HeroCarousel component for both sites Single carousel implementation in packages/shared-ui: auto-rotation, dots, pause/play, aria-live, crossfade, data-driven slides. Site-specific title and action buttons passed as Svelte 5 snippets. --- main/src/routes/+page.svelte | 176 +++-------------- packages/shared-ui/src/index.ts | 1 + .../shared-ui/src/lib/HeroCarousel.svelte | 138 +++++++++++++ pigeonhole/src/routes/+page.svelte | 183 ++++-------------- 4 files changed, 205 insertions(+), 293 deletions(-) create mode 100644 packages/shared-ui/src/lib/HeroCarousel.svelte diff --git a/main/src/routes/+page.svelte b/main/src/routes/+page.svelte index e8e7479..273b555 100644 --- a/main/src/routes/+page.svelte +++ b/main/src/routes/+page.svelte @@ -5,18 +5,12 @@ import logoSrc from '$lib/assets/logo.png?enhanced'; import anniversaryImgSrc from '$lib/assets/anniversary.png?enhanced'; - import { GitHubIcon } from '@dovecot/shared-ui'; + import { GitHubIcon, HeroCarousel } from '@dovecot/shared-ui'; import proLogoSrc from '$lib/assets/pro-logo.png?enhanced'; - let activeSlide = $state(0); - let intervalId: any; - let isPaused = $state(false); - const slides = [ { - tagText: "", - tagClass: "text-on-surface-variant border-outline-variant bg-surface-container-low", badge: "The Secure, High Performance Email Server", badgeClass: "text-primary", badgeIcon: "", @@ -27,8 +21,6 @@ imageClass: "max-w-l" }, { - tagText: "", - tagClass: "text-tertiary border-tertiary-container/30 bg-tertiary-container/10", badge: "Celebrating 25 Years", badgeClass: "text-tertiary", badgeIcon: "workspace_premium", @@ -39,145 +31,41 @@ imageClass: "shadow-lg border border-outline-variant/30" } ]; - - function startInterval() { - if (isPaused) return; - intervalId = setInterval(() => { - activeSlide = (activeSlide + 1) % slides.length; - }, 12000); - } - - function resetInterval() { - if (intervalId) { - clearInterval(intervalId); - } - startInterval(); - } - - function togglePause() { - isPaused = !isPaused; - if (isPaused) { - if (intervalId) clearInterval(intervalId); - } else { - startInterval(); - } - } - - $effect(() => { - startInterval(); - return () => { - if (intervalId) { - clearInterval(intervalId); - } - }; - }); - -
-
+{#snippet heroTitle()} + + Dovecot + +{/snippet} - -
- -
- - - Dovecot - - -
- {#each slides as slide, idx} -
-
-
- {#if slide.tagText} - - {slide.tagText} - - {/if} -
-
- - {#if slide.badgeIcon} - - {/if} - {slide.badge} - -
-
-

- {@html slide.headline} -

-

- {slide.description} -

-
- {/each} -
- - -
- - -
-
-
- {#each slides as slide, idx} -
- -
- {/each} -
-
-
- - -
- {#each slides as _, idx} - - {/each} - -
+{#snippet heroActions()} + + + Download + + + + Code + + + Documentation + +{/snippet} - -
- Slide {activeSlide + 1} of {slides.length}: {slides[activeSlide].badge} -
-
+ +
diff --git a/packages/shared-ui/src/index.ts b/packages/shared-ui/src/index.ts index e01c221..16cbb86 100644 --- a/packages/shared-ui/src/index.ts +++ b/packages/shared-ui/src/index.ts @@ -1,5 +1,6 @@ export { default as GitHubIcon } from './lib/GitHubIcon.svelte'; export { default as CodeBlock } from './lib/CodeBlock.svelte'; export { default as Footer } from './lib/Footer.svelte'; +export { default as HeroCarousel } from './lib/HeroCarousel.svelte'; export { default as Header } from './lib/Header.svelte'; export { default as SiteLayout } from './lib/SiteLayout.svelte'; diff --git a/packages/shared-ui/src/lib/HeroCarousel.svelte b/packages/shared-ui/src/lib/HeroCarousel.svelte new file mode 100644 index 0000000..47a484e --- /dev/null +++ b/packages/shared-ui/src/lib/HeroCarousel.svelte @@ -0,0 +1,138 @@ + + +
+
+ + +
+ +
+ + {@render title()} + +
+ {#each slides as slide, idx} +
+
+
+ + {#if slide.badgeIcon} + + {/if} + {slide.badge} + +
+
+

+ {@html slide.headline} +

+

+ {@html slide.description} +

+
+ {/each} +
+ +
+ {@render actions()} +
+
+ + +
+
+
+ {#each slides as slide, idx} +
+ +
+ {/each} +
+
+
+ + {#if rotating} + +
+ {#each slides as _, idx} + + {/each} + +
+ + +
+ Slide {activeSlide + 1} of {slides.length}: {slides[activeSlide].badge} +
+ {/if} +
diff --git a/pigeonhole/src/routes/+page.svelte b/pigeonhole/src/routes/+page.svelte index 571cfc1..30d158d 100644 --- a/pigeonhole/src/routes/+page.svelte +++ b/pigeonhole/src/routes/+page.svelte @@ -1,168 +1,53 @@ Pigeonhole - Sieve Support for Dovecot - -
-
- - -
- -
- - - Pigeonhole - - -
- {#each slides as slide, idx} -
-
-
- {#if slide.tagText} - - {slide.tagText} - - {/if} -
-
- - {#if slide.badgeIcon} - - {/if} - {slide.badge} - -
-
-

- {slide.headline} -

-

- {@html slide.description} -

-
- {/each} -
- - -
+{#snippet heroTitle()} + + Pigeonhole + +{/snippet} - -
-
-
- {#each slides as slide, idx} -
- -
- {/each} -
-
-
- - - {#if slides.length > 1} -
- {#each slides as _, idx} - - {/each} - -
+ + Download + + + + Code + + + Documentation + +{/snippet} - -
- Slide {activeSlide + 1} of {slides.length}: {slides[activeSlide].badge} -
- {/if} -
+ +
From ec85c6f470bc92ac32bb4cedc56f14b3206df59e Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Tue, 15 Sep 2026 17:21:53 -0600 Subject: [PATCH 02/11] css: drop @tailwindcss/forms The only two elements in the repo (search boxes on /news and /security) are fully styled with explicit utility classes, so the plugin restyles nothing. Remove the @plugin lines and the devDependency (lock hand-edited; npm remote fetch is disabled in this environment). --- main/src/routes/layout.css | 1 - package-lock.json | 24 ------------------------ package.json | 1 - packages/shared-ui/src/lib/layout.css | 1 - pigeonhole/src/routes/layout.css | 1 - 5 files changed, 28 deletions(-) diff --git a/main/src/routes/layout.css b/main/src/routes/layout.css index 9d167ef..2173654 100644 --- a/main/src/routes/layout.css +++ b/main/src/routes/layout.css @@ -3,7 +3,6 @@ @import 'tailwindcss'; @source "../../../packages/shared-ui/src/**/*.svelte"; @import "../../../packages/shared-ui/src/lib/layout.css"; -@plugin '@tailwindcss/forms'; @theme { --color-on-surface: #1a1c1c; diff --git a/package-lock.json b/package-lock.json index 062748b..dee825b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,6 @@ "@sveltejs/enhanced-img": "^0.11.0", "@sveltejs/kit": "^2.70.3", "@sveltejs/vite-plugin-svelte": "^7.3.0", - "@tailwindcss/forms": "^0.5.11", "@tailwindcss/vite": "^4.3.3", "gray-matter": "^4.0.3", "svelte": "^5.56.10", @@ -1169,19 +1168,6 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/@tailwindcss/forms": { - "version": "0.5.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.11.tgz", - "integrity": "sha512-h9wegbZDPurxG22xZSoWtdzc41/OlNEUQERNqI/0fOwa2aVlWGu7C35E/x6LDyD3lgtztFSSjKZyuVM0hxhbgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "mini-svg-data-uri": "^1.2.3" - }, - "peerDependencies": { - "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1" - } - }, "node_modules/@tailwindcss/node": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", @@ -2214,16 +2200,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/mini-svg-data-uri": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", - "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", - "dev": true, - "license": "MIT", - "bin": { - "mini-svg-data-uri": "cli.js" - } - }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", diff --git a/package.json b/package.json index bd84546..1f5bd0b 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,6 @@ "@sveltejs/enhanced-img": "^0.11.0", "@sveltejs/kit": "^2.70.3", "@sveltejs/vite-plugin-svelte": "^7.3.0", - "@tailwindcss/forms": "^0.5.11", "@tailwindcss/vite": "^4.3.3", "gray-matter": "^4.0.3", "svelte": "^5.56.10", diff --git a/packages/shared-ui/src/lib/layout.css b/packages/shared-ui/src/lib/layout.css index 998d35e..9d3aff8 100644 --- a/packages/shared-ui/src/lib/layout.css +++ b/packages/shared-ui/src/lib/layout.css @@ -1,6 +1,5 @@ @import 'tailwindcss'; @source "../../src/**/*.svelte"; -@plugin '@tailwindcss/forms'; @theme { --radius-default: 0.25rem; diff --git a/pigeonhole/src/routes/layout.css b/pigeonhole/src/routes/layout.css index 60e7235..22be46a 100644 --- a/pigeonhole/src/routes/layout.css +++ b/pigeonhole/src/routes/layout.css @@ -3,7 +3,6 @@ @import 'tailwindcss'; @source "../../../packages/shared-ui/src/**/*.svelte"; @import "../../../packages/shared-ui/src/lib/layout.css"; -@plugin '@tailwindcss/forms'; @theme { --color-on-surface: #1a1c1c; From c760b9dc401bdf4f844536717d5dc081cf6caa37 Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Tue, 15 Sep 2026 17:25:18 -0600 Subject: [PATCH 03/11] codeblock: replace copyId state map with a single boolean Each CodeBlock instance renders exactly one copy button, so the copiedStates Record keyed by a required copyId prop (plus copyIdSuffix plumbing through RepoSection) collapsed to one local copied: boolean. Verified with svelte-check: 0 errors. --- main/src/routes/download/RepoSection.svelte | 6 ------ main/src/routes/download/eol/+page.svelte | 1 - packages/shared-ui/src/lib/CodeBlock.svelte | 19 +++++++++---------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/main/src/routes/download/RepoSection.svelte b/main/src/routes/download/RepoSection.svelte index 5416b36..5a523f4 100644 --- a/main/src/routes/download/RepoSection.svelte +++ b/main/src/routes/download/RepoSection.svelte @@ -10,13 +10,11 @@ let { version, // '2.4' | '2.3' pgpKeyId, // key id to show - copyIdSuffix = '', // appended to copy IDs pgpNote, // custom text after "packages" in PGP description navExtra, // optional extra nav links snippet }: { version: string; pgpKeyId: string; - copyIdSuffix?: string; pgpNote?: string; navExtra?: Snippet; } = $props(); @@ -140,7 +138,6 @@ {/if} @@ -149,7 +146,6 @@ {/if} @@ -158,7 +154,6 @@ {/if} @@ -170,7 +165,6 @@ {#if currentDist.packages} diff --git a/main/src/routes/download/eol/+page.svelte b/main/src/routes/download/eol/+page.svelte index f36857b..bd1665f 100644 --- a/main/src/routes/download/eol/+page.svelte +++ b/main/src/routes/download/eol/+page.svelte @@ -78,7 +78,6 @@ diff --git a/packages/shared-ui/src/lib/CodeBlock.svelte b/packages/shared-ui/src/lib/CodeBlock.svelte index fd05d9e..a3a4f72 100644 --- a/packages/shared-ui/src/lib/CodeBlock.svelte +++ b/packages/shared-ui/src/lib/CodeBlock.svelte @@ -1,17 +1,16 @@ @@ -20,16 +19,16 @@
{code}
- {copiedStates[copyId] ? 'Copied to clipboard' : ''} + {copied ? 'Copied to clipboard' : ''}
From 1c33d3460a8f75c4af7c7d43faee8163617688bd Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Tue, 15 Sep 2026 17:28:30 -0600 Subject: [PATCH 04/11] header: drop unused logoHref prop SiteLayout is the only caller and never passed it; the logo always points at the site root. --- packages/shared-ui/src/lib/Header.svelte | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/shared-ui/src/lib/Header.svelte b/packages/shared-ui/src/lib/Header.svelte index 3373877..5315b49 100644 --- a/packages/shared-ui/src/lib/Header.svelte +++ b/packages/shared-ui/src/lib/Header.svelte @@ -17,7 +17,6 @@ logoTitleClass = 'text-white', logoSubtitleClass = 'text-white/60 font-light', logoImgClass = 'h-8 w-auto', - logoHref = '/', navItems = [], githubUrl = 'https://github.com/dovecot/core/' } = $props<{ @@ -28,7 +27,6 @@ logoTitleClass?: string; logoSubtitleClass?: string; logoImgClass?: string; - logoHref?: string; navItems: NavItem[]; githubUrl?: string; }>(); @@ -56,7 +54,7 @@
- +
From cf2e369600533010539fb6f67c576456a1d434b5 Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Tue, 15 Sep 2026 17:28:46 -0600 Subject: [PATCH 05/11] css: drop unused font-body-sm theme vars Zero usages in either site. --- packages/shared-ui/src/lib/layout.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/shared-ui/src/lib/layout.css b/packages/shared-ui/src/lib/layout.css index 9d3aff8..52f4f98 100644 --- a/packages/shared-ui/src/lib/layout.css +++ b/packages/shared-ui/src/lib/layout.css @@ -18,14 +18,12 @@ --font-body-md: "Inter", sans-serif; --font-headline-xl: "Manrope", sans-serif; --font-headline-lg: "Manrope", sans-serif; - --font-body-sm: "Inter", sans-serif; --font-size-label-md: 12px; --font-size-headline-lg-mobile: 24px; --font-size-body-md: 16px; --font-size-headline-xl: 48px; --font-size-headline-lg: 32px; - --font-size-body-sm: 14px; } /* Smooth active state transitions — avoid 'all' to keep focus rings instant (WCAG 2.4.7) */ From aa9d73b9c71b166c39fc8164491ebdc34d0ec3fe Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Tue, 15 Sep 2026 17:30:02 -0600 Subject: [PATCH 06/11] header: remove inert animate-fade-in class The class matched no CSS anywhere; the mobile nav rendered without any animation. --- packages/shared-ui/src/lib/Header.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared-ui/src/lib/Header.svelte b/packages/shared-ui/src/lib/Header.svelte index 5315b49..5cdb964 100644 --- a/packages/shared-ui/src/lib/Header.svelte +++ b/packages/shared-ui/src/lib/Header.svelte @@ -117,7 +117,7 @@ {#if mobileMenuOpen} -
Date: Tue, 15 Sep 2026 18:44:23 -0600 Subject: [PATCH 09/11] pigeonhole: Add a Security page --- pigeonhole/src/routes/+layout.svelte | 1 + pigeonhole/src/routes/security/+page.svelte | 68 +++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 pigeonhole/src/routes/security/+page.svelte diff --git a/pigeonhole/src/routes/+layout.svelte b/pigeonhole/src/routes/+layout.svelte index b4c4469..9ec980f 100644 --- a/pigeonhole/src/routes/+layout.svelte +++ b/pigeonhole/src/routes/+layout.svelte @@ -16,6 +16,7 @@ { name: 'Download', href: '/download' }, { name: 'Documentation', href: 'https://doc.dovecot.org/', target: '_blank' }, { name: 'Support', href: '/support' }, + { name: 'Security', href: '/security' }, { name: 'Dovecot', href: 'https://dovecot.org/', target: '_blank' } ]; diff --git a/pigeonhole/src/routes/security/+page.svelte b/pigeonhole/src/routes/security/+page.svelte new file mode 100644 index 0000000..0b67cad --- /dev/null +++ b/pigeonhole/src/routes/security/+page.svelte @@ -0,0 +1,68 @@ + + Security - Pigeonhole + + +
+ +
From d675494c4246d84da75c57a1bb9f7c433f5e1961 Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Tue, 15 Sep 2026 19:46:26 -0600 Subject: [PATCH 10/11] security pages: link to Dovecot Pro Security Advisories Add a banner on both the Dovecot and Pigeonhole Security pages linking to the Dovecot Pro (commercial product) security advisory program, noting that Pro advisories may also apply to the Community Editions. --- main/src/routes/security/+page.svelte | 24 ++++++++++++++++++++ pigeonhole/src/lib/assets/pro-logo.png | Bin 0 -> 11050 bytes pigeonhole/src/routes/layout.css | 2 +- pigeonhole/src/routes/security/+page.svelte | 24 ++++++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 pigeonhole/src/lib/assets/pro-logo.png diff --git a/main/src/routes/security/+page.svelte b/main/src/routes/security/+page.svelte index 8539d58..6787a87 100644 --- a/main/src/routes/security/+page.svelte +++ b/main/src/routes/security/+page.svelte @@ -78,6 +78,30 @@
+ +
+
+
+ +
+
+
+

Dovecot Pro Security Advisories

+

+ Dovecot Pro is the commercial product and maintains its own security advisory program. Pro advisories may also be applicable to Dovecot Community Edition. +

+
+ + View Advisories + +
+
+

Security Advisories

diff --git a/pigeonhole/src/lib/assets/pro-logo.png b/pigeonhole/src/lib/assets/pro-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9aa07328f957300c7c75f10de315793a4f4d8a05 GIT binary patch literal 11050 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 literal 0 HcmV?d00001 diff --git a/pigeonhole/src/routes/layout.css b/pigeonhole/src/routes/layout.css index 22be46a..523c12a 100644 --- a/pigeonhole/src/routes/layout.css +++ b/pigeonhole/src/routes/layout.css @@ -1,4 +1,4 @@ -@import url('https://fonts.bunny.net/css?family=inter:400,500,600,700|manrope:600,700,800|material-symbols:100,200,300,400,500,600,700'); +@import url('https://fonts.bunny.net/css?family=inter:400,500,600,700|manrope:600,700,800|space-grotesk:400,500,600,700|ubuntu-sans:400,500,700|material-symbols:100,200,300,400,500,600,700'); @import 'tailwindcss'; @source "../../../packages/shared-ui/src/**/*.svelte"; diff --git a/pigeonhole/src/routes/security/+page.svelte b/pigeonhole/src/routes/security/+page.svelte index 0b67cad..78a300d 100644 --- a/pigeonhole/src/routes/security/+page.svelte +++ b/pigeonhole/src/routes/security/+page.svelte @@ -64,5 +64,29 @@
+ + +
+
+
+ +
+
+
+

Dovecot Pro Security Advisories

+

+ Dovecot Pro is the commercial product and maintains its own security advisory program. Pro advisories may also be applicable to Dovecot and Pigeonhole Community Edition. +

+
+ + View Advisories + +
+
From 6b0bd7e9f5a98a5fa3e13912e98220396ebbe6ab Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Tue, 15 Sep 2026 19:59:37 -0600 Subject: [PATCH 11/11] Update check-spelling metadata --- .github/actions/spelling/expect.txt | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 720b614..c71fba1 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -4,29 +4,17 @@ CVEs DFBB Dists gpgkeys -hubfs idx ircs -ISPs -LGPLv listinfo -napt -nbaseurl -nenabled -ngpgcheck -ngpgkey -nname noopener noreferrer -nsudo -nyum onsubmit openemailsurvey -opsz prerender proactively rce sitemap SLAs splitscreen -wght +yeswehack