JetBrains Mono, and an editor that follows the page - #108
Merged
Conversation
One variable file per subset covers the whole weight range, and they are the bytes AlgoJudge-Docs ships. One theme token reaches every fixed-pitch surface.
vs in light, vs-dark in dark, through the prop rather than a remount. Monaco measures a glyph once, so the face arriving late needs remeasureFonts.
getComputedStyle reports the stack that was asked for; only the protocol says which face drew the glyphs, and a fall back to Consolas is invisible without it.
Monaco paints its own ground and nothing else, so against a card of the same colour there was nothing saying where a solution may be typed. The border is on the wrapper, in the semantic colour an installation can theme.
kisielewski
deleted the
feat/jetbrains-mono-and-an-editor-that-follows
branch
September 7, 2026 00:19
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four things, and the first of them turned out to be already done.
Inter and Lato were already here
Six files in
src/assets/fonts/: Lato 400 and 700 acrosslatinandlatin-ext, which is the product's own face, and Inter 600 across both, whichexists to draw the wordmark and nothing else. Nothing to add; neither is touched.
JetBrains Mono
Two files, byte for byte the ones
AlgoJudge-Docsships, for the reasonLato's four are Keycloak's: one typeface across the product rather than one per
repository. Variable, so one file per subset carries the whole weight range — a
bold token in a highlighted source comes out of the face rather than out of
synthetic bolding, and it is two files where per-weight slices would be four.
public/OFL-JetBrainsMono.txtbeside the other two.font-display: swap, like Lato and unlike Inter: Inter blocks because a fallbackoverflows the drawing it paints, and there is nothing here to overflow.
typography.tsgainsfontFamilyMonospace, and one key is the whole of it —Mantine emits
--mantine-font-family-monospaceand every fixed-pitch surfacereads it:
<Code>,<JsonInput>, the gutter beside a highlighted source, andthe editor, which takes the same constant rather than writing a stack of its own.
PRODUCT_STACKis untouched.verify-hero.mjsasserts/^Lato/on the body,and its face counts are family-filtered before they are counted, so a third
family is invisible to them.
The editor follows the page, and has an edge
theme="vs-dark"was hard-coded with a comment arguing that a code surface isread differently from a page of prose. It takes
vsorvs-darkfromuseComputedColorSchemenow, through the prop rather than a remount — akey=would throw away the undo stack and the scroll position mid-solution.
Monaco painted its own ground and nothing else, so against a card of the same
colour there was no edge and where a solution may be typed was a guess. The
frame is on the wrapper, not on
.monaco-editor— that class is Monaco's — andin
--mantine-color-default-border, whichbranding.tswrites an installation'sown border colour into.
monaco.editor.remeasureFonts()is new work the font made necessary. Monacomeasures a glyph once at start-up and lays every column out from that number; at
font-display: swapthe first editor of a cold load mounts on the fallback, andwithout the call the text is one width and the cursor another.
The check, and why it is not
getComputedStyleverify-editor.mjsasks the browser which face painted the glyphs, over theDevTools protocol.
getComputedStyle(el).fontFamilyreports the stack that wasasked for, so a silent fall back to Consolas is invisible to it — the same
class of defect that shipped in
AlgoJudge-Docslast week and was caught only byeye. The harness gains one capability,
paintedWith(selector), andscripts/verify/README.mdgains the two traps it carries: the answer covers anode's own text runs, so
.view-linesreports nothing and.view-line > spaniswhat has the glyphs; and an empty editor paints nothing at all, so a line has to
be typed before measuring.
Five sabotages, each red and each restored from a file copy: the
fontFamilyoption removed (
24× Consolas), the theme pinned back to dark (light / vs-dark),the
.woff2pointed at nothing, the border removed (0px), and the border madetransparent (
1px rgba(0, 0, 0, 0)).Verified
lint,lint:deps,typecheck,build, the ten file-reading checks, and thewhole
check:ui: 52 passed — one more than before, the new script. Run twicein full, the second time because adding a wrapper element could have moved a
width assertion elsewhere. It did not.
The suite was pointed at a dev server of this branch's own with
APP=, and thatwas checked rather than assumed: exactly two Vite processes on the machine
throughout, and Playwright started neither.