mash. / foundry
Foundry, in detail.
Foundry is the one tool on this site that’s live, so it gets its own page. It’s a design system built as a working app: the page layouts, colour themes and components the rest of my tools copy from. It has no accounts and no real data, and you can poke at it at foundry.mashreeves.com.
Why it exists
Built once, so nothing gets rebuilt.
Six of my other apps had each built their own sign-in, two-factor and account-deletion screens. That’s the job a reference app is for. So the four page layouts (sign in, the app itself, notices and errors), three colour themes (light, dark and high contrast) and the components are built once here, then copied out.
It’s deliberately not a package. You open it next to the app you’re building and copy what you need, so nothing depends on Foundry at runtime. The catch is that nothing keeps a copy in step either: there’s no version pin and no check. Drift is the accepted cost, and it has already happened.
What’s in it
Working pages, not pictures of them.
- Calendar and Gantt chart. On a phone you hold an event for a moment, then drag it, and you can pull the bottom edge to change how long it lasts. A red line shows today. The Gantt chart lays tasks out on a weekly timeline with progress and milestones.
- Approvals. Raise a request and its amount decides who has to approve it. Approve, reject or send it back with a comment. You can’t decide your own request.
- Tickets. A helpdesk queue with internal notes that only the support team can see. A ticket can’t be resolved while its approval is still open.
- Invoices. Every amount is worked out in exact pounds and pence, VAT is shown for each rate, and it prints on A4.
- File upload. Each file shows whether it uploaded, was blocked by the virus scan, failed (with a Retry button) or wasn’t accepted, and why.
- The smaller ones. Chat, forum, news board, document library, stepper, activity timeline, toasts and loading placeholders.
Whatever you add on the demo pages lasts until you close the browser, and files you choose are never kept.
How it’s checked
The same gates as everything else.
Symfony 7.4 with Twig, Stimulus and Turbo, and no Node build step. Bootstrap 5.3 is themed before it’s imported, not overridden afterwards. The style check, PHPStan at level 8 and the test suite all have to pass. A separate script re-checks every colour pair in the themes against the WCAG contrast formula, and it’s re-run whenever a colour changes. Each new feature gets its own accessibility audit, and the fixes show up in the history.
I used a commercial admin template for visual reference only. None of its code, CSS, JavaScript, icons or images are in here.
What went wrong
Three things that broke.
From the project’s own record, written down when each one happened.
- An empty form crashed it. Submitting the feedback form with nothing in it gave a 500 error instead of the validation messages. A test written before the fix caught it. Symfony turns an empty text field into null, not the empty string the object’s default suggests, unless you say otherwise. Each text field now sets its empty value explicitly.
- Tests failed because of the last run. The rate limiter kept its used-up quota between test runs, so a suite run within 15 minutes of the previous one failed for reasons that had nothing to do with the code. It now has its own storage, wiped before every run.
- The tests were looking at the wrong error page. The test setup defaulted to debug mode, which shows Symfony’s own error page instead of the site’s. A test of the 404 page would have been checking something no visitor ever sees. The fix is scoped to the one test that needs it.
Status
Why I call it live.
Nothing here is called live until it’s deployed, backed up, and I’ve restored from one of those backups. Foundry is the one tool that meets that today. The hosting and backup details are on the trust page. It’s a showcase on demo data, not a product with users, so the stakes are low. The rule is the same either way.
Last checked against Foundry’s own release notes on 6 October 2026. If something here is out of date, the release notes are right and this page is wrong.
Back to everything I’m building, or the standard it’s built to.