Cortex
Cortex is an online IQ and reasoning test in two sizes: a free quick test with its result straight after, and a full test behind payment. Use it for an IQ test, an aptitude or pre-employment test, a placement or entry test, any assessment with a free taster and a paid product. The look is clean and ultra-modern: lab white with a fine measurement grid, glass panels, a precise grotesque set big and tight, and an iridescent light in three colors. On the home page a figure matrix solves itself in a glass window. The demo is a fictional test, Quotient.
Cortex comes in two variants, chosen when you create the site: files/Sanity (static pages with a few
server routes, any host with server functions) and EmDash (--cms emdash,
rendered on request on Cloudflare). The pages and the tests are the same in both.
Pages and their content
Section titled “Pages and their content”| Page | Edit it in |
|---|---|
| Home | Pages → Home page (a list of sections) |
| The quick test (time limit, rules, parts, runner texts, norms) | Pages → Test page (quick test) |
| The full test (parts and their time limits, the offer, payment texts, norms) | Pages → Full test page |
| The result (texts, what each score means, certificate, debrief call) | Pages → Result page |
| Method (parts, scoring, limits) | Pages → Method page |
| Journal, contact, 404 | Pages → the page’s own entry |
| Questions for the verbal and arithmetic parts (prompt, options, right answer, level) | Content → Questions |
| Articles | Content → Journal |
| Name, email, disclaimer, navigation, header button, profiles | Pages → Site settings |
| Buttons, labels, chat, emails, game texts | Content → Interface texts |
| Privacy, terms, refunds | Pages → Legal |
In headlines, words wrapped in *stars* are set in the iridescent gradient, as in “Measure how you
*think*.”
Two tests
Section titled “Two tests”The quick test (/test) is free: four parts on one clock (25 minutes in the demo), 30 questions,
and the result straight after, with no account and no email.
- Matrices: 3 × 3 figure matrices with the last cell missing. Easy items change one property along the rows or columns (shape, count, fill or turn), harder ones three or four at once; the hardest are line patterns laid over each other.
- Number series: a step, a growing step, two series woven together, multiplying, adding the two previous terms, two operations in turn; harder items hide a term in the middle.
- Spatial: shapes made of squares, turned in the head; the harder items use mirror images as decoys.
- Verbal: analogies, the odd one out, meanings and short logic, from your question bank.
The full test (/full) is built like the tests psychologists give: seven parts, 106 questions,
about an hour. Each part has its own time limit and closes for good when its time is up or the
visitor moves on. It adds three parts:
- Arithmetic: short problems in words, from your question bank.
- Digit memory: a row of digits shows for a few seconds, then the visitor picks the row they saw; rows grow longer, and the last third asks for them in reverse order.
- Symbol search: is either of two symbols in a row? As many as possible in two minutes.
The full test has its own page (/full), where it’s offered until paid for, a place in the
navigation and a home section showing both tests side by side; every quick result ends with the offer
too (a comparison of the two tests, the price and what’s included).
Matrices, series, spatial, digit memory and symbol search items are generated for every test, so no two tests are the same and no answer can be looked up. Parts, questions per part and time limits are in each test’s page in the CMS. The clock only runs while questions are on screen; progress is kept in the browser, so a closed tab can be resumed. Answers are chosen by click, tap or the keys A–F (or 1–6; Y and N in symbol search).
The answer key never reaches the browser. A test is built on the server from a signed token and
scored there too; the browser gets back a sealed result it can’t read. Set TEST_SECRET (a long
random string) before launch: it signs every test and seals every result.
Results and payment
Section titled “Results and payment”A result opens at /result?r=…: the sealed result is in the link, so it works on any device and
needs no database. It shows the IQ score with a 90 % confidence interval, the percentile and band on a
bell curve, a profile across the parts (a radar and a bar for each, with what the score means) and
every question right or wrong. A full test’s report adds a printable certificate with the visitor’s
name and a report code, and a debrief call (Cal.com).
The offer (on /full and under a quick result) opens Stripe Checkout. After paying, the visitor comes back to
/full?session_id=… and starts the full test whenever they like (the link is emailed too, by the
webhook); the server checks the session is paid when the test starts, and the result’s link is
emailed when it’s done.
To take payments with Stripe: set STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET (a webhook to
/api/stripe/webhook for checkout.session.completed), and put a one-time Price id in Pages → Full
test page → The full test. With Lemon Squeezy instead, set its three variables (a webhook to
/api/lemonsqueezy/webhook for order_created) and put the variant id (a number) in the same field;
after paying, the link that starts the test comes by email. Until both the key and the Price id are set, the full test opens without
payment and says it’s a demo, so the template works out of the box.
How raw scores become IQ scores is in each test’s page → Norms and score bands: the mean and standard deviation of the total raw score and of each part in your norm group, the reliability (it sets the confidence interval) and the bands with their texts. The demo values are illustrative. Replace them with figures from your own test takers before you publish scores. Reports are worked out when they’re opened, so new norms apply to earlier results too.
Integrations
Section titled “Integrations”Everything works without keys; each feature switches on with its variables in .env.example.
| Feature | Where | Service |
|---|---|---|
| The paid full test | /full and the offer under a quick result |
Stripe or Lemon Squeezy |
| Accounts | Saved results, members-only articles | Clerk |
| Links by email | The full test after payment (webhook), its report when it’s done | Resend |
| Debrief call | A full test’s report, loads on click; a preview of the calendar until connected | Cal.com |
| Newsletter | Home and journal pages, with a welcome email | Supabase |
| Contact form | Contact page; messages go to the email in Site settings | Resend |
| AI chat | On every page except the tests; answers about both tests, the result and the method, never about answers | Claude |
| Search | ⌘K or the search button: both tests, method, articles, contact | built in, or Algolia |
| Analytics | Every page; Google Analytics only after consent | Plausible, Umami, Google Analytics |
Sections
Section titled “Sections”The home page is built from these sections, in any order: Hero (the living matrix), The four abilities (cards that stack as you scroll, each subtest in motion), How it works (a line of light that draws itself), Try a question (one matrix to answer on the spot), The report (a bell curve that draws itself, an example score counting up), The method in short, The two tests (side by side, with the full test’s price), Questions, Latest articles, Newsletter and Closing call. With reduced motion everything stands still.
Colors and brand
Section titled “Colors and brand”src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three colors: the accent
(electric indigo: buttons, links, the answer that locks in), and the second and third (cyan and
magenta), which make the iridescent light with it. Buttons are darkened until their white text is
readable; the gradient in headlines uses shades of all three checked against the page; a color that
can’t get there stops the build with a message. Brand also sets the three fonts (text, headings, data)
and the corners. The site opens in the day theme even when the visitor’s system is dark; the toggle
switches to the night, near-black with a glowing grid, and the browser remembers the choice.
Languages
Section titled “Languages”Cortex is ready for more languages: see Languages. A test started in a language uses that language’s texts and bank questions.
Accounts
Section titled “Accounts”With Clerk set up, visitors can sign in (Clerk’s hosted page; no Clerk script
on your site): an account link appears in the header, every result gets “Save to my account”, and
/account lists the saved results with their scores. They’re kept in the user’s private metadata on
Clerk, so there’s no database. Articles can be members-only too (Members only, in the article).
Without Clerk, results are their links: emailed after a full test, and they open on any device.
The 404 page
Section titled “The 404 page”A small game, Triad: nine cards, each with one to three circles, triangles or squares, solid, striped or outlined. Find three cards whose shape, count and fill are each all the same or all different, with a click, a tap or the keys 1–9. A wrong triad costs five seconds; sixty seconds in all. The best score is kept in the visitor’s browser.
AI assistants and search engines
Section titled “AI assistants and search engines”AGENTS.mddescribes the project for coding assistants (Claude Code reads it throughCLAUDE.md, Cursor through.cursor/rules/), including where the test engine is and what must never reach the browser./llms.txtlists your pages and articles for AI assistants, in every language.- Pages carry JSON-LD: questions as a
FAQPage, the scoring as aHowToand each article as aBlogPosting. The result page is left out of the sitemap.
Commands
Section titled “Commands”pnpm dev # local site, editor at /keystaticpnpm build # production buildpnpm cms sanity schema|seed # move content to Sanity (see Content → Sanity)In the EmDash variant: npm run dev, npm run deploy (Cloudflare) and npm run emdash:schema
(after changing the content model).