Kevin’s story was buried, and every update needed a developer
The Kevin Popke Foundation turns one man’s memory into grants for Florida veteran organizations: First Sergeant Kevin Popke, “50” to his friends. In the family’s words, the old site was built to check a box.
That added up to two problems. A story problem: memorial sites that lead with the organization get the order backwards. A maintenance problem: a small team has to keep grants, events, and stories current on its own, or the site is stale by Veterans Day.
Constraints: $2,000, three homepage concepts due in week one, a late-August launch, and real content only (no invented grantees, no unconfirmed tax-status claims). I handled strategy, design, and build solo, with the Popke family as stakeholders.
Four decisions that made the site run itself
1. Put the person before the organization
The strongest memorial foundation sites (Murph, Schmitz, Morelli, Arbery) name the person early, say who they were before asking for anything, and frame giving as continuing that person’s work. That became the homepage order: person, purpose, programs. Kevin’s portraits fill the hero, and “Who is Kevin Popke?” comes before the ways to help.
2. Same copy across three concepts
All three concepts shipped with identical copy and section flow, so the family compared design, not content, in one sitting. They chose Modern Community because it read most clearly as a professional nonprofit, the brief’s first ask. The family tartan stayed in ribbons and edges, and its loudest red went to buttons, because a full page of it reads as a clearance sale.
3. One source-of-truth frame, one width token
Midway through, the build looked about 70% unfinished. Figma had two homepages labeled “final,” and container widths had drifted between 72rem and 74rem. I locked one frame as the source of truth and collapsed every width into a single token, and the missing pieces came back in the next pass.
4. Build the CMS instead of buying plugins
Going headless (WordPress → WPGraphQL → Next.js on Vercel) broke the plugin ecosystem, and the budget ruled out paid licenses. So I built one plugin, kpf-core. It reads each page design and lists every heading, button, and paragraph that renders as a plain field, so nobody guesses field names. Queries are stored as allowlisted JSON instead of PHP, which keeps executable code out of the database, and accessibility is a site-wide preset that’s on by default.
Results: 98–100 on PageSpeed, and updates without a developer
What shipped: six templates (Home, About, Events, Contact, Blog archive, Blog post) across desktop, tablet, and mobile; kpf-core, with 11 self-serve modules replacing separate SEO, forms, image optimization, snippets, and accessibility plugins; and a CSS manifest mapping every Figma section to classes, with tokens layered primitive → semantic → component.
| Measure | Result | Source |
|---|---|---|
| PageSpeed, desktop | 98 / 100 / 100 / 100 | PageSpeed Insights, Oct 16, 2026 |
| PageSpeed, mobile | 95 / 100 / 100 / 100 | PageSpeed Insights |
| GTmetrix | Grade A (98% performance) | GTmetrix, Aug 27, 2026 |
| Grants shown on About | $86,000+ | Live site |
| Budget | $2,000 | Fixed fee |
When the foundation gave $10,000 to Operation Warrior Resolution in June 2026, the whole update started from a photo of the check: grantee and grant logged, logo optimized, About page total recalculated. No template edits, no redeploy.
What I’d do again (and differently)
- Research should change structure, not just styling. One round of studying memorial sites reordered the whole homepage.
- Hold content constant when comparing concepts. The family compared all three in one sitting because nothing else was changing.
- Write the design contract before the code. The manifest gave every Figma section a class name up front, so “is this built yet?” had a yes-or-no answer.
I still maintain the site pro bono, which makes a good long-term usability test for the CMS: if I can’t update it in five minutes, neither can they.