MAMIKEU
Bilingual institutional website for a Cameroonian NGO, built to win institutional funders. Next.js 16, Payload CMS, WCAG 2.2 AA.
About This Project
A bilingual institutional website for the Association des Enfants de Marie Mikeu (MAMIKEU), a rural NGO in Dschang–Fokoué, Cameroon, working with vulnerable families across education, health, agriculture and environment, and entrepreneurship. The site exists to convince institutional funders rather than to collect donations; it takes no payments. It had to answer four questions in the first few seconds: who are you, what do you do, who do you help, and how can I contribute. French and English content sit side by side in the CMS, with no string hardcoded in either language.
At a Glance
74
pre-rendered pages
303
unit + E2E tests
AA
WCAG 2.2, enforced in tokens
33
decision records
- Role
- Design direction, content model, full build, accessibility, testing and deployment — solo.
- Timeline
- 4 – 16 September 2026 · 52 commits
- Status
- Feature-complete · awaiting client photography and final copy
The Problem
Late in the build, the client corrected the audience: the site exists to attract NGOs and funders, not to be read by the rural population it serves. Three constraints had been built for a reader on an entry-level phone over 2G. Rather than quietly reversing them, I logged the premise change as its own decision record and relaxed exactly three constraints — animation, typography and the JavaScript budget — each re-measured before and after. Reduced motion, no-JavaScript readability and AA contrast did not move.
Technologies Used
Framework
Next.js 16.3 (App Router, Cache Components), React 19
CMS
Payload 3.88 mounted in the same app
Read through its local API; 11 collections and 7 globals
Database
SQLite via @payloadcms/db-sqlite
One host, one process, one file to back up
Styling & motion
Tailwind 4, CSS, GSAP 3.15 + ScrollTrigger
GSAP only for scroll-linked effects, only where pages move
Validation
Zod at every trust boundary
Same schema server-side and client-side
Testing
Vitest (84), Playwright (219, desktop + mobile)
Tests encode the design rules, not just behaviour
Key Features
- •Fully bilingual: every interface string and every content field in French and English
- •Four programmes presented as full-width numbered chapters instead of generic icon cards
- •Project archive with filters and story-driven project pages with a reading-position rail
- •Draggable before/after photo curtain, keyboard-operable, with a no-JavaScript fallback
- •News, downloadable reports and an impact and transparency page
- •French-native admin, with an editor's guide written for first-time CMS users
- •Half-filled CMS produces a shorter page, never a broken one
- •Consent and permission tracked as fields on photographs and partner logos
Challenges & Solutions
01Serving a licensed typeface without redistributing it
The client chose Palatino Linotype, which can't legally be converted and served. Hand-written @font-face rules resolve local('Palatino Linotype') first, so Windows and macOS visitors download zero bytes; everyone else gets a subset of TeX Gyre Pagella, a metric-compatible twin under a licence that permits it.
02A budget test that reported half the payload
The JavaScript budget test summed compressed sizes inside async handlers and read the total after a fixed wait, so the homepage measured 67 KB while shipping 141 KB. Every response is now awaited, the test fails if no scripts were seen, and router prefetches are blocked so pages aren't charged for their neighbours.
03An entrance animation that cost four seconds of LCP
Scroll-reveal elements start invisible, so the browser recorded no Largest Contentful Paint until JavaScript ran: 6.7 s on throttled mobile. The first row of every list now skips the reveal, bringing LCP to 3.0 s, pinned by a DOM-level regression test.
04The no-JavaScript test that passed on a blank page
The first check read computed opacity, which is 1 even inside a display: none ancestor — so it passed while pages shipped their whole <main> inside React's hidden streaming container. The test now walks up from <main> for hidden ancestors across nine paths, with JavaScript disabled and under reduced motion.
Outcome & Lessons
Largest Contentful Paint lands between 2.55 s and 3.07 s across all six page kinds on throttled mobile, with zero layout shift. The build is feature-complete and runs as a self-contained preview — the build seeds its own SQLite file, so a reviewer gets the full site and admin from a git push, with no third-party services. Nothing was invented to fill the gaps: missing facts hide their section, and placeholders say plainly what's still owed.
- •A decision that rests on a fact about the audience has to name that fact, so it can fall when the fact does.
- •A design rule nobody can fail is a suggestion: the tests encode the design system, from icon imports to overflow at every width.
- •Measurements need testing too: a budget test that under-reports is worse than none, because it signs things off.