From 34e82f482bb6ebf3b44c6e349452d619bb91f2af Mon Sep 17 00:00:00 2001 From: Stanislav Zhuk Date: Fri, 23 Oct 2026 17:44:00 +0300 Subject: [PATCH] feat(home): add linkable section headings and refresh landing page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Short Summary (TL;DR) Every home page section now has a linkable heading, so `/#supporters` and the other sections are easy to find and share, and the landing page gets a consistent layout, up-to-date feature copy, and logos that match in both themes and on phones. ## How This PR Solves The Issue - Each section opens with a label that carries its anchor, a title, and a lead, styled by shared `section-*` classes in `global.css`: `#features`, `#stack`, `#benefits`, `#quickstarts`, `#blog`, `#supporters` (with `#featured-sponsors`, `#github-sponsors`, `#github-contributors`), and `#repositories`. The `/sponsor` page links to `#featured-sponsors`. - The unlabeled logo strips become the Stack and Quickstarts sections. Quickstart logos are named, and both rows use one gray, inverted in dark mode. Stack adds MariaDB, the default database, and Solr; Quickstarts show the six most used project types from `/usage-stats/`, now including Symfony. - Features copy is corrected against the current docs: "Custom Deployments" claimed deployment, which DDEV does not do, so it is now "Hosting Integrations"; MariaDB and Mutagen are named. - On phones, featured sponsor logos are smaller, titles wrap evenly, and logo rows no longer leave one logo alone on a line. - Tag1, Lullabot, and Craft CMS get their smaller size from padding in their SVG `viewBox` instead of a home page class, so the README badges show them in proportion too. Only MacStadium and Redfin, which must look larger, keep a class, and the add-sponsor skill now says so; the entries for four former sponsors are gone. An accessibility review of the home page found issues outside this change, to fix in a follow-up PR: the hero terminal animation ignores reduced motion and is read aloud mid-typing, "Get Started" and "Documentation" are links marked as buttons, the mobile menu covers its own button and does not close on Escape, and blog card titles are not headings. ## Manual Testing Instructions Compare https://20261023-stasadev-supporters.ddev-com-front-end.pages.dev/ with https://ddev.com/ in light and dark mode, at desktop and phone width: - Every section heading links to itself, and https://20261023-stasadev-supporters.ddev-com-front-end.pages.dev/#supporters and `#featured-sponsors` land on those sections. - Stack shows two rows of five logos on desktop and a two-column grid on a phone, all in the same gray. - Quickstarts show six named logos, and "All quickstarts →" opens the docs. - Featured Sponsors fit several logos per row on a phone, and Tag1, Lullabot, and Craft CMS are in proportion with their neighbors on the home page and in https://20261023-stasadev-supporters.ddev-com-front-end.pages.dev/resources/featured-sponsors.svg. - On https://20261023-stasadev-supporters.ddev-com-front-end.pages.dev/sponsor/, the "ddev.com" link in the Featured Sponsor benefit goes to `/#featured-sponsors`. 🤖 Developed with assistance from [Claude Code](https://claude.ai/code) Co-Authored-By: Claude Opus 5.5 --- .claude/skills/add-sponsor/SKILL.md | 11 +- public/logos/apache.svg | 2 +- public/logos/craft-cms.svg | 2 +- public/logos/dark-lullabot.svg | 4 +- public/logos/frankenphp.svg | 2 +- public/logos/lullabot.svg | 2 +- public/logos/mariadb.svg | 1 + public/logos/mysql.svg | 2 +- public/logos/nginx.svg | 2 +- public/logos/node.svg | 2 +- public/logos/php.svg | 2 +- public/logos/postgresql.svg | 5 +- public/logos/redis.svg | 11 +- public/logos/solr.svg | 1 + public/logos/symfony.svg | 1 + public/logos/tag1.svg | 2 +- src/components/AppLogos.astro | 64 +++++++---- src/components/Benefits.astro | 10 +- src/components/BlogFeatures.astro | 9 +- src/components/Contributors.astro | 27 +++-- src/components/FeaturedSponsors.astro | 26 ++--- src/components/Features.astro | 24 ++-- src/components/RepoCard.astro | 4 +- src/components/SoftwareLogos.astro | 157 +++++++++++++++----------- src/pages/index.astro | 13 ++- src/pages/sponsor.astro | 2 +- src/styles/global.css | 23 ++++ 27 files changed, 241 insertions(+), 170 deletions(-) create mode 100644 public/logos/mariadb.svg create mode 100644 public/logos/solr.svg create mode 100644 public/logos/symfony.svg diff --git a/.claude/skills/add-sponsor/SKILL.md b/.claude/skills/add-sponsor/SKILL.md index d794ad464..8af5e4d11 100644 --- a/.claude/skills/add-sponsor/SKILL.md +++ b/.claude/skills/add-sponsor/SKILL.md @@ -151,10 +151,13 @@ rsvg-convert -w 800 -b '#0d1117' ~/tmp/badge-darkmode.svg -o ~/tmp/badge-darkmod View both PNGs. The new logo must be visible, in proportion with its neighbors, and not cut off. A badge route that fails to build usually means `sharp` could not read the SVG, so go back to step 2. Then check `/#supporters` -on the dev server in both themes, using the theme toggle in the header. If the -logo looks too large or small there next to the others, add a Tailwind height -class for it to `nudges` in `src/components/FeaturedSponsors.astro`, keyed by -`name`. +on the dev server in both themes, using the theme toggle in the header, at +desktop and phone width. If the logo looks too large there next to the others, +add padding to its `viewBox` as in step 2 and set `height` to match, which also +shrinks it in the badges. Only a logo that must look larger than its tight +`viewBox` allows gets an entry in `nudges` in +`src/components/FeaturedSponsors.astro`, keyed by `name`, with a height for +phones and one from `sm` up, such as `h-10 sm:h-15`. ## 6. Commit diff --git a/public/logos/apache.svg b/public/logos/apache.svg index a3ca448e7..240fdc682 100644 --- a/public/logos/apache.svg +++ b/public/logos/apache.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/logos/craft-cms.svg b/public/logos/craft-cms.svg index 657256a0e..b6622b894 100644 --- a/public/logos/craft-cms.svg +++ b/public/logos/craft-cms.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/logos/dark-lullabot.svg b/public/logos/dark-lullabot.svg index 803634210..d96cc6cff 100644 --- a/public/logos/dark-lullabot.svg +++ b/public/logos/dark-lullabot.svg @@ -1,8 +1,8 @@ + \ No newline at end of file diff --git a/public/logos/lullabot.svg b/public/logos/lullabot.svg index 8d6b71d1e..d009dfb77 100644 --- a/public/logos/lullabot.svg +++ b/public/logos/lullabot.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/logos/mariadb.svg b/public/logos/mariadb.svg new file mode 100644 index 000000000..54e2fae09 --- /dev/null +++ b/public/logos/mariadb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/logos/mysql.svg b/public/logos/mysql.svg index 0f7e9ca40..650edc4a2 100644 --- a/public/logos/mysql.svg +++ b/public/logos/mysql.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/logos/nginx.svg b/public/logos/nginx.svg index 6ec682d3c..62508ff17 100644 --- a/public/logos/nginx.svg +++ b/public/logos/nginx.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/logos/node.svg b/public/logos/node.svg index 917bc2516..9a70e6d1b 100644 --- a/public/logos/node.svg +++ b/public/logos/node.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/logos/php.svg b/public/logos/php.svg index c9edee578..5d2e755e3 100644 --- a/public/logos/php.svg +++ b/public/logos/php.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/logos/postgresql.svg b/public/logos/postgresql.svg index 1d81fbb9b..eff27cc7b 100644 --- a/public/logos/postgresql.svg +++ b/public/logos/postgresql.svg @@ -1,4 +1 @@ - + \ No newline at end of file diff --git a/public/logos/redis.svg b/public/logos/redis.svg index d8095e762..251a6d42d 100644 --- a/public/logos/redis.svg +++ b/public/logos/redis.svg @@ -1,10 +1 @@ - - - - - - - - - - + \ No newline at end of file diff --git a/public/logos/solr.svg b/public/logos/solr.svg new file mode 100644 index 000000000..f1e01d13c --- /dev/null +++ b/public/logos/solr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/logos/symfony.svg b/public/logos/symfony.svg new file mode 100644 index 000000000..794d0520c --- /dev/null +++ b/public/logos/symfony.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/logos/tag1.svg b/public/logos/tag1.svg index d67c93802..da12930ab 100644 --- a/public/logos/tag1.svg +++ b/public/logos/tag1.svg @@ -1,4 +1,4 @@ - + diff --git a/src/components/AppLogos.astro b/src/components/AppLogos.astro index 9cbc66c0f..35b74988c 100644 --- a/src/components/AppLogos.astro +++ b/src/components/AppLogos.astro @@ -1,34 +1,54 @@ --- /** - * Supported framework names and logos used on the homepage. + * Quickstarts for popular CMSes and frameworks, as named logos, used on the + * homepage: the six project types used most on /usage-stats/, in that order, + * which "App Ready" in Features.astro names in the same order. */ +const QUICKSTART_URL = "https://docs.ddev.com/en/stable/users/quickstart/" + const logos = [ { name: "Drupal", src: "/logos/drupal.svg", quickstart: "drupal", extraClasses: [] }, { name: "WordPress", src: "/logos/wordpress.svg", quickstart: "wordpress", extraClasses: [] }, + { name: "Laravel", src: "/logos/laravel.svg", quickstart: "laravel", extraClasses: ["w-7"] }, { name: "TYPO3", src: "/logos/typo3.svg", quickstart: "typo3", extraClasses: [] }, - { name: "Magento 2", src: "/logos/magento.svg", quickstart: "magento-2",extraClasses: [] }, - { name: "Backdrop", src: "/logos/backdrop.svg", quickstart: "backdrop", extraClasses: [] }, { name: "Craft CMS", src: "/logos/craft.svg", quickstart: "craft-cms", extraClasses: ["w-7"] }, - { name: "Laravel", src: "/logos/laravel.svg", quickstart: "laravel", extraClasses: ["w-7"] }, + { name: "Symfony", src: "/logos/symfony.svg", quickstart: "symfony", extraClasses: [] }, ] --- -
-
-
- { - logos.map((logo) => ( -
- - {`${logo.name} - -
- )) - } -
-
+
+ +

+ Your CMS or framework, ready to go. +

+

+ Step-by-step setup for these and many more, for new and existing projects. +

+ + + All quickstarts → +
diff --git a/src/components/Benefits.astro b/src/components/Benefits.astro index 59edbdc5a..0e5e239f1 100644 --- a/src/components/Benefits.astro +++ b/src/components/Benefits.astro @@ -40,13 +40,13 @@ const features = [ ---
-
+
-

Benefits

-

+

+

Made for people that make websites. - -

+

+

DDEV handles Docker so you and your team can focus on your work.

diff --git a/src/components/BlogFeatures.astro b/src/components/BlogFeatures.astro index bdfa24d34..834951da9 100644 --- a/src/components/BlogFeatures.astro +++ b/src/components/BlogFeatures.astro @@ -14,12 +14,13 @@ const recentPosts = posts .slice(0, 3) --- -
+
-

- Latest Blog Posts -

+ +

+ Latest from the blog. +

{recentPosts.map((post) => )} diff --git a/src/components/Contributors.astro b/src/components/Contributors.astro index a91bb7601..2cebdce86 100644 --- a/src/components/Contributors.astro +++ b/src/components/Contributors.astro @@ -8,30 +8,35 @@ import Sponsors from "./Sponsors.astro" const contributors = await getContributors() --- -
+
-
-

- Our Wonderful Supporters -

+
+ +

+ Our wonderful supporters. +

+

+ These organizations and people keep DDEV free and open source.{" "} + Join them. +

-

- Featured Sponsors +

-

- GitHub Sponsors +

+ GitHub Sponsors

-

- GitHub Contributors +

+ GitHub Contributors

{ diff --git a/src/components/FeaturedSponsors.astro b/src/components/FeaturedSponsors.astro index bc97fa2ac..7836d6797 100644 --- a/src/components/FeaturedSponsors.astro +++ b/src/components/FeaturedSponsors.astro @@ -2,20 +2,14 @@ import featuredSponsors from "../featured-sponsors.json" /** - * Sketchy array of classes that should be applied to specific logos - * in this context. Match the name from `featured-sponsors.json` if - * you need to add one. + * Heights for logos that must render larger than the rest, keyed by the name + * in `featured-sponsors.json`, for phones and from `sm` up. A logo that should + * look smaller gets padding in its SVG `viewBox` instead, which the README + * badges also respect. */ const nudges = { - Tag1: "h-9 self-center", // Added self-center to align it vertically - "Oliver Wand": "h-12 w-12", - DrupalEasy: "h-10", - "Redfin Solutions": "h-16 w-16", - MacStadium: "h-15", - Lullabot: "h-9", - "Craft CMS": "h-11", - undpaul: "h-9", - "1xINTERNET": "h-11", + "Redfin Solutions": "h-11 w-11 sm:h-16 sm:w-16", + MacStadium: "h-10 sm:h-15", } // Separate lead sponsors from regular sponsors @@ -36,7 +30,7 @@ regularSponsors.map((sponsor) => {
{leadSponsors.map((sponsor) => ( { {/* Regular Sponsors Section */}
{regularSponsors.map((sponsor) => ( +
-

Features

-

+

+

Running in minutes, ready for the long haul.

-

+

Start new DDEV projects in seconds. Customize, share, and extend with ease.

diff --git a/src/components/RepoCard.astro b/src/components/RepoCard.astro index 1955c7058..a043560cd 100644 --- a/src/components/RepoCard.astro +++ b/src/components/RepoCard.astro @@ -19,10 +19,10 @@ const repoData = await getRepoDetails(name)
-
+

{name}

-
- +
+ +

+ Your stack, your versions. +

+

+ Choose PHP and Node.js versions, a database, a web server, and extra + services for each project. +

+
+ { + rows.map((row) => ( +
+ {row.map((logo) => ( + + {logo.title} + + ))} +
+ )) + }
diff --git a/src/pages/index.astro b/src/pages/index.astro index d8038588d..405f3736c 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -33,9 +33,18 @@ const jsonUrl = new URL(`/blog/feed.json`, Astro.site).toString()
-
+
+
+ +

+ Explore the code. +

+

+ DDEV and its tools are developed in the open on GitHub. +

+