Design system
Every token and component in both themes. Dark is the default; light mirrors every token.
Brand
Wordmark in Inter with tight tracking. The mark is three rising blocks: a staircase and a build pipeline. Monochrome, legible at 16px.
Dark
Light
Color
Deeply desaturated. Incorrect is coral, never red, and always paired with the rubric bullets that were missed. Correct is teal, not green.
Dark
- --bgPage background#0F1117
- --surfaceCards#161923
- --surface-raisedModals, popovers#1C2030
- --borderDefault border, unassessed heatmap cell#262B3A
- --border-strongInputs, emphasised dividers#343A4D
- --textPrimary text#E4E7EF
- --text-mutedSecondary text#9AA3B8
- --text-faintPlaceholders, tertiary#6B7488
- --accentPrimary actions, focus rings#7C9EFF
- --accent-hoverPrimary hover#93AEFF
- --accent-subtleSelected / hover backgrounds#1B2440
- --tealCorrect, 70–100#4DD4C0
- --amberPartial, 40–69#E8B84B
- --coralIncorrect, 0–39 (never pure red)#F2766B
- --violetCoding questions#A78BFA
- --emberWarm brand accent: hero, Sprint, never a score#FFA76A
Light
- --bgPage background#FBFBFD
- --surfaceCards#FFFFFF
- --surface-raisedModals, popovers#FFFFFF
- --borderDefault border, unassessed heatmap cell#E6E8EF
- --border-strongInputs, emphasised dividers#D3D7E2
- --textPrimary text#1A1D26
- --text-mutedSecondary text#5A6175
- --text-faintPlaceholders, tertiary#868DA1
- --accentPrimary actions, focus rings#4B6FE0
- --accent-hoverPrimary hover#3D5FCC
- --accent-subtleSelected / hover backgrounds#EEF2FE
- --tealCorrect, 70–100#12A594
- --amberPartial, 40–69#C08A1E
- --coralIncorrect, 0–39 (never pure red)#D9544A
- --violetCoding questions#7C5CE0
- --emberWarm brand accent: hero, Sprint, never a score#D9661F
Track hues
Every track and course carries its own colour, derived from its slug by hueFor() — twelve angles on the oklch wheel at a fixed lightness per theme, so they all land at the same contrast. Identity only: a score is still coral, amber or teal.
Dark
- 40
- 65
- 95
- 130
- 160
- 185
- 210
- 240
- 265
- 290
- 315
- 345
Light
- 40
- 65
- 95
- 130
- 160
- 185
- 210
- 240
- 265
- 290
- 315
- 345
Typography
Inter for UI, JetBrains Mono for code and every number. Scale 12 / 13 / 14 / 16 / 20 / 28 / 40. Body line-height 1.6, headings 1.25. Resist bold.
Dark
Body text at 14px. Secondary text is muted, tertiary is faint. Numbers are always mono: 74% · 12/15 · 00:42
const score = 0.7 * (passed / total) * 100 + 0.3 * review;
Light
Body text at 14px. Secondary text is muted, tertiary is faint. Numbers are always mono: 74% · 12/15 · 00:42
const score = 0.7 * (passed / total) * 100 + 0.3 * review;
Form controls
Borders over shadows. Inputs use the strong border and the accent focus ring.
Dark
At least 10 characters.
Light
At least 10 characters.
Badges
6px radius. Track status, question type and level badges carry meaning through both colour and text.
Dark
Light
Cards, tabs, tables
10px radius on cards, one-pixel borders, no shadows.
Dark
| Session | Tracks | Level | Score |
|---|---|---|---|
| Sep 18 | .NET + SQL Server | Junior | 48 |
| Sep 12 | Python + PostgreSQL | Mid | 67 |
| Sep 4 | React + TypeScript | Mid | 79 |
Light
| Session | Tracks | Level | Score |
|---|---|---|---|
| Sep 18 | .NET + SQL Server | Junior | 48 |
| Sep 12 | Python + PostgreSQL | Mid | 67 |
| Sep 4 | React + TypeScript | Mid | 79 |
Overlays
Dialog, popover, tooltip, menu and toast. The popover shadow is the only shadow in the product.
Dark
Light
Readiness score
Always labelled with the level. Reveals over 600ms; respects prefers-reduced-motion.
Dark
Needs work for Junior backend roles
You would pass some rounds and stumble in others. Two or three subtopics account for most of the gap.
Beta — 62 questions, coverage is partial
Light
Needs work for Junior backend roles
You would pass some rounds and stumble in others. Two or three subtopics account for most of the gap.
Beta — 62 questions, coverage is partial
Subtopic heatmap
Coral 0–39, amber 40–69, teal 70–100, neutral for not yet assessed. The percentage is printed in every cell so it reads without colour.
Dark
C#
- Value vs reference types82%
- Collections & LINQ74%
- async/await & Task61%
- OOP & interfaces88%
- Generics70%
- Exceptions45%
- Records & structs—
- IDisposable & using66%
- Delegates & events38%
- Strings & spans—
SQL Server
- Joins74%
- Aggregates & GROUP BY68%
- Window functions52%
- CTEs60%
- Indexes & seeks vs scans31%
- Execution plans28%
- Transactions & isolation44%
- Deadlocks—
- Normalization79%
- Stored procedures55%
- NULL semantics63%
- Query tuning36%
- 0–39
- 40–69
- 70–100
- Not yet assessed
Dense variant (dashboard)
SQL Server
- 74%
- 68%
- 52%
- 60%
- 31%
- 28%
- 44%
- —
- 79%
- 55%
- 63%
- 36%
Light
C#
- Value vs reference types82%
- Collections & LINQ74%
- async/await & Task61%
- OOP & interfaces88%
- Generics70%
- Exceptions45%
- Records & structs—
- IDisposable & using66%
- Delegates & events38%
- Strings & spans—
SQL Server
- Joins74%
- Aggregates & GROUP BY68%
- Window functions52%
- CTEs60%
- Indexes & seeks vs scans31%
- Execution plans28%
- Transactions & isolation44%
- Deadlocks—
- Normalization79%
- Stored procedures55%
- NULL semantics63%
- Query tuning36%
- 0–39
- 40–69
- 70–100
- Not yet assessed
Dense variant (dashboard)
SQL Server
- 74%
- 68%
- 52%
- 60%
- 31%
- 28%
- 44%
- —
- 79%
- 55%
- 63%
- 36%
Grading
Every rubric bullet with its status, weight and the evidence from the user's own answer. The score is arithmetic on this list.
Dark
IQueryable builds an expression tree, translated by the provider
From your answer:
IQueryable keeps an expression tree that EF turns into SQL
Covered30IEnumerable executes in memory on the client
From your answer:
IEnumerable just iterates objects already in memory
Covered25Filtering an IQueryable happens in the database
From your answer:
the where goes to the database I think
Partial25Both are deferred until enumeration
Not mentioned
Missing10Consequence: calling ToList() too early pulls the whole table
Not mentioned
Missing10
Factual error · −5 — You said IQueryable is always faster; it is not when the whole set is needed.
- returns_empty_for_no_ordersPassed
- counts_multiple_ordersPassed
- ignores_cancelledFailed
input: 3 orders, 1 cancelled actual: 3
- hidden_1 Hidden testPassed
- hidden_2 Hidden testFailed
input: 2 customers, 0 orders
Compile error
Solution.cs(12,9): error CS0103: The name 'orders' does not exist in the current context
- compilesFailed
Light
IQueryable builds an expression tree, translated by the provider
From your answer:
IQueryable keeps an expression tree that EF turns into SQL
Covered30IEnumerable executes in memory on the client
From your answer:
IEnumerable just iterates objects already in memory
Covered25Filtering an IQueryable happens in the database
From your answer:
the where goes to the database I think
Partial25Both are deferred until enumeration
Not mentioned
Missing10Consequence: calling ToList() too early pulls the whole table
Not mentioned
Missing10
Factual error · −5 — You said IQueryable is always faster; it is not when the whole set is needed.
- returns_empty_for_no_ordersPassed
- counts_multiple_ordersPassed
- ignores_cancelledFailed
input: 3 orders, 1 cancelled actual: 3
- hidden_1 Hidden testPassed
- hidden_2 Hidden testFailed
input: 2 customers, 0 orders
Compile error
Solution.cs(12,9): error CS0103: The name 'orders' does not exist in the current context
- compilesFailed
Session
Progress rail (answered, skipped, current, unanswered; violet tick = coding) and static code display. Monaco arrives in build step 6 using the same tokens.
Dark
SELECT c.name, COUNT(o.id) AS ordersFROM customers AS cLEFT JOIN orders AS o ON o.customer_id = c.idWHERE c.created_at >= DATE '2026-01-01'GROUP BY c.nameHAVING COUNT(o.id) > 3ORDER BY orders DESC;Light
SELECT c.name, COUNT(o.id) AS ordersFROM customers AS cLEFT JOIN orders AS o ON o.customer_id = c.idWHERE c.created_at >= DATE '2026-01-01'GROUP BY c.nameHAVING COUNT(o.id) > 3ORDER BY orders DESC;Panes and keycaps
Elevation is a translucent wash over the canvas plus a hairline border and a lit top edge, not a lighter solid colour. Keycaps are lit on top and shadowed underneath.
Dark
Resting pane
A wash, a hairline, a lit edge.
Hover pane
Brightens and firms its border on hover.
Readiness
68
Junior
Streak
12
consecutive days
Answered
244
graded, all time
Due for review
23
scheduled
Practice over twelve weeks
Light
Resting pane
A wash, a hairline, a lit edge.
Hover pane
Brightens and firms its border on hover.
Readiness
68
Junior
Streak
12
consecutive days
Answered
244
graded, all time
Due for review
23
scheduled
Practice over twelve weeks
Calibration
Confidence is asked before grading, never after. The gap between what you claimed and what you scored is the part no competitor measures: being sure and wrong is what ends interviews.
Dark
Optional. It is how we tell you whether you know what you know.
Did you know what you knew?
You rated yourself 18 points higher than you scored. The answers you were sure about are the ones to revise.
Confidence gap
+18 overconfident
Average gap
31
What each confidence level actually scored
- Guessing44% · 1
- Fairly sure64% · 2
- Sure31% · 2
Bar is what you scored, the notch is what you claimed. 5 answers rated.
Confidently wrong
You were sure about these and scored below half. These are the ones that end an interview, because you would never think to revise them.
- Indexes & seeks vs scanssaid 90 · scored 24
- Execution planssaid 90 · scored 38
Light
Optional. It is how we tell you whether you know what you know.
Did you know what you knew?
You rated yourself 18 points higher than you scored. The answers you were sure about are the ones to revise.
Confidence gap
+18 overconfident
Average gap
31
What each confidence level actually scored
- Guessing44% · 1
- Fairly sure64% · 2
- Sure31% · 2
Bar is what you scored, the notch is what you claimed. 5 answers rated.
Confidently wrong
You were sure about these and scored below half. These are the ones that end an interview, because you would never think to revise them.
- Indexes & seeks vs scanssaid 90 · scored 24
- Execution planssaid 90 · scored 38