Every case study was a standalone Astro page with its own layout, its own component imports and its own way of breaking on mobile.
Twenty-two of them. Each one built at a different time by a different combination of people, with whatever patterns felt right that week. Changing shared behavior (a hero transition, a spacing value, a navigation pattern) meant touching every file individually. The September 2025 release that started consolidating them changed around 200 files: roughly 13,000 insertions and 39,000 deletions, most of it duplicated layout code that no longer needed to exist.
We needed every case study to run through a single template and a shared set of modules. The migration took five months.
What lives in the testbed
We built a case study called testbed. It’s marked private: true and never appears on the public site. Its only purpose was to stress-test the template system before we touched real client work.
We loaded it with every module combination we could think of: heroes with video, text columns in every layout variant, cards with tight spacing, sliders, quotes, image-text blocks at different measures. If the template could handle the testbed, it could handle anything real.
The testbed: every module combination we could imagine, validated before touching real client work.
The testbed absorbed the risk that would otherwise land on a real client page. Rendering bugs surfaced in private, not in production.
The timeline
September 2025: The first release introduced unified blocks: accordion, floating nav, slider. Around 200 files changed in a single PR.
November 2025: CaseStudyTemplate.astro went live. We migrated Air first as a proof of concept, then activated Token, Hayah, Atelier100, London Design Festival, London Design Biennale and Bhutan in a batch.
Late November 2025: The testbed launched. Every edge case we could imagine, validated against the real template.
January 2026: The remaining 16 case studies were rebuilt using the module system. Migration complete. Twenty of the 22 now run through the unified template. None fall back to the legacy rendering path.
A case study today
An .mdx file with frontmatter and container directives. Media is referenced by short asset IDs that the rendering layer resolves to optimized images or video. The Air case study has 30 directive blocks (hero, text columns, cards, sliders, quotes) and the entire page is just markdown and asset references.
Directives and asset IDs on the left. The rendered page on the right.
The template reads the MDX, maps each directive to its module component and outputs the page. Next-project navigation is randomized — a small UX detail that means a repeat visitor never hits the same suggestion twice.
The work that paid for itself
The testbed. Building something nobody will ever see felt like wasted effort at the time. Five months later, it had earned its place: every bug it caught in private was a bug that didn’t ship to a client’s page. We still add module combinations to it whenever we build something new.