The platform, not the school
This whole school is one file away from being yours.
Everything you are looking at — the palette, the name, the catalogue, the certificate wording, the pricing table, the voice tutor — comes out of a single configuration file. Change it and the site, the signed-in application and the issued PDF all follow. No fork, no find-and-replace, and nothing else in the codebase names a school.
The mechanism
One file in, four surfaces out.
What a buyer actually edits
shared/brand.config.ts, and nothing else.
A maritime school, a franchise operator, a manufacturer inducting line staff — the same code, a different config. The snippet beside this is a complete, working configuration for a different school; drop it in and the deployment you are reading becomes that school on the next build.
The certificate is the tell. Its title, preamble, attestation, seal, identifier prefix and verification URL are all in that file — and the accreditation line is an empty string by default, so a school that holds no accreditation prints none. You cannot claim a regulator's approval by leaving a placeholder in.
The token contract, measured
Every text tier is computed against the surface it sits on, not eyeballed.
These ratios are calculated in the browser from the palette currently loaded. Change the config, reload, and this table changes with it — which is how a buyer finds out their brand colour fails on a label before their customers do.
| Token | Value | Used for | Contrast on surface | WCAG |
|---|---|---|---|---|
| ink | #F4F1F7 | Body text and headings | 15.55 : 1 | AAA |
| ink-2 | #C3BAD2 | Secondary text and every field label | 9.34 : 1 | AAA |
| ink-3 | #9A90AC | Eyebrows, captions, table meta | 5.77 : 1 | AA |
| accent | #A98CFF | Primary action | 6.53 : 1 | AA |
| trim | #C7CBD8 | Corner ticks, rules, rings, seal | 10.74 : 1 | AAA |
| ok | #5CD6A0 | Passed | 9.60 : 1 | AAA |
| warn | #F0B84E | Retake | 9.67 : 1 | AAA |
| bad | #FF7A6E | Failed | 6.85 : 1 | AA |
| info | #7BC5F0 | Informational | 9.19 : 1 | AAA |
What comes with it
The platform
Courses, modules, written lessons, worksheets as CSV, module checks, a final assessment, certificates with public verification, student progress, an admin dashboard, bulk enrolment and analytics.
The demo school
4 courses, 32 modules and 131 lessons of real material, loaded, so the platform is never shown empty. Keep it, replace it, or hide it by deleting four strings from the catalogue array.
The voice tutor
An ElevenLabs Agents session handed the exact lesson the student is reading. Point it at your own agent in your own workspace; voice minutes are billed to you, not resold by us.
Your Stripe
Your students pay into your own Stripe account on your own deployment. The money never touches ours, and that is a property of the architecture rather than a promise.
Your domain, your database
One Vercel project and one Postgres database per school. Nothing is multi-tenant, so there is no other school's data anywhere near yours.
The runbook
PROVISION.md: the exact sequence to stand a school up, the env block, the seed, the handover, and the deprovision steps with a date.
The certificate, as this config renders it
This certifies that
has completed every lesson and passed the written assessment for every module of this course.
What this is not: it is not a hosted platform with a monthly seat fee, and we are not trying to be one. It is a single-tenant deployment you own, on your infrastructure, with your Stripe keys, priced as a build. If what you want is a subscription with a support desk behind it, one of the hosted platforms is a better answer and we will say so on the call.
