From DrDrij's review of the v2.5.0 build on QuantEcon/lecture-python-programming#363 (item 8a): inline equations read large in relation to the copy around them. That is real and it is measurable — inline maths on the review deployment computes 21.78px inside 18px prose, a ratio of 1.210. But nothing in this theme sets that number, and the Sphinx lectures it replaces are 2.2% away at 1.184, which is MathJax's default rather than a QuantEcon setting. Neither build has ever chosen the size its maths renders at. So what has to be settled is not whether the theme is wrong, but what ratio QuantEcon wants inline maths to sit at against the copy — and that is a choice to take before any CSS is written.
Where 1.21 comes from
The winning rule is KaTeX's own, in the stylesheet the theme self-hosts. node_modules/katex/dist/katex.css:143 (KaTeX 0.16.33) declares .katex { font: normal 1.21em KaTeX_Main, Times New Roman, serif; line-height: 1.2; … }, and the theme adds nothing against it: grepping styles/ and app/ across the v2.5.0 tree for katex returns one substantive hit, app/links.ts:2, the import that self-hosts the sheet. The only other .katex rules in the build come from upstream @myst-theme/styles/math.css — .katex-display { margin: 0 !important } and a .katex .eqn-num { opacity: 0 } block — and neither touches size. KaTeX's 1.21em therefore resolves against .article's 18px (styles/quantecon.css:314, font-size: 1.125rem) and lands at 21.78px.
Measured, both builds
Chromium at 1440×900, computed styles on the live pages — the review deployment at https://6a9b93b9108dd4beb6bebadc--epic-agnesi-957267.netlify.app/functions and https://python-programming.quantecon.org/functions.html. Every mjx-container on the Sphinx page carries jax="CHTML", and MathJax writes its inline scale onto each one as a style attribute.
| Build |
Prose |
Inline maths |
Ratio |
What sets the maths size |
| This theme (review deployment) |
18px |
21.780px |
1.210 |
KaTeX default .katex { font: normal 1.21em … } |
| Sphinx lectures |
18px |
21.312px |
1.184 |
MathJax 3 CHTML matchFontHeight, written inline as font-size: 118.4% |
| Sphinx lectures at 900px wide |
16px |
18.928px |
1.183 |
same mechanism, off a 16px root (font-size: 118.3%) |
The same glyphs, at two different scales
Canvas actualBoundingBoxAscent at 100px per em, measured on each live page, with a deliberately unavailable family as a fallback control (italic 44.434 / upright 44.873 — distinct from every row below, so the named faces really did resolve). KaTeX's and MathJax's TeX faces come out metrically identical, because both descend from the same Computer Modern designs. The two builds are drawing the same glyphs; only the scale differs.
| Face |
x-height |
cap-height |
KaTeX_Math italic / MJXTEX-I italic |
44.200 |
68.300 |
KaTeX_Main / MJXTEX |
43.100 |
68.300 |
Source Sans 3 Variable (this theme's prose) |
48.609 |
65.631 |
Source Sans Pro (Sphinx prose) |
48.600 |
65.600 |
Scaled to the sizes each build actually renders, that is the optical relationship a reader sees.
| Metric, maths ÷ prose |
This theme |
Sphinx |
| x-height (italic maths variables against the copy) |
1.100 |
1.077 |
| cap-height |
1.259 |
1.233 |
So the "maths reads bigger than the copy" character DrDrij describes is present in the Sphinx lectures too, almost identically. Under the recorded stance — parity in idea over engineering parity — that is a reason to treat this as an improvement request, not a reason to close it.
Where the two builds genuinely diverge: narrow viewports
The Sphinx builds step their root size by viewport (16px below 992px, 18px at and above) and reach 18px content that way. This theme sets a flat 18px on .article and leaves the root at 16px deliberately, so the reader's own browser font-size preference still applies; the reasoning is written out at styles/quantecon.css:55-74. The consequence for maths is that the ratio stays ~2% apart at every width but the absolute size does not.
| Viewport |
Sphinx inline maths |
This theme |
Difference |
| 1440px |
21.312px |
21.780px |
+2.2% |
| 900px |
18.928px |
21.780px |
+15.1% |
Nobody has ever chosen QuantEcon's maths scale
There is no considered QuantEcon value to defer to here, and this is the finding that makes deciding deliberately worth the trouble. quantecon-book-theme's layout.html:43-46 configures MathJax with svg: { fontCache: 'global', scale: 0.92, displayAlign: "center" }, while the lecture repo loads the CHTML-only bundle (lectures/_config.yml:79, mathjax_path: https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js). That bundle carries no SVG output jax, there is no chtml key anywhere in the book theme's source, and every container in the rendered DOM is jax="CHTML" — so the requested 0.92 scale has never taken effect on any build QuantEcon has shipped, and 118.4% is MathJax's own matchFontHeight filling the vacuum. The only intent on record points at a smaller ratio than either build renders today.
That is a defect in its own right and it does not depend on which option below is taken, because the key is mis-named at whatever ratio is chosen. Owner: whoever takes this decision forward files it, against QuantEcon/quantecon-book-theme — that is where the svg: key lives and every lecture site inherits it — naming the lecture repo's mathjax_path as the other half of the pair. Three separate triage passes have now found this and none has filed it.
What a change costs
Four of the six visual snapshots contain maths and all four move if a value is set: intro.png and sidebar-open.png (inline $e^{i\pi} + 1 = 0$ at tests/visual/fixture/intro.md:8) and features.png and history-open.png (the display block at features.md:39-41, $r$/$\beta$/$c$ in the table at :80-82, $x \in \mathbb{R}$ at :90). lists.png and notebook.png have no maths. That is 16 PNGs across desktop-chrome-{darwin,linux} and mobile-chrome-{darwin,linux}. A change of option 2's size sits well under the maxDiffPixelRatio: 0.01 budget at tests/visual/theme.spec.ts:34, which is exactly the blind spot #113 records. Any .katex override the theme carries also has to be re-verified when KaTeX 0.18's class rename lands (#118).
Options
1. Leave it at KaTeX's 1.21. Costs nothing and moves no baselines. For: the two builds are within 2.2% of each other at desktop width, the character is inherent to TeX faces set against a humanist sans, and the Sphinx lectures have shipped this relationship for years with no reported complaint. Against: it is the largest of the plausible values, and it is a default rather than a decision.
2. Match Sphinx's 1.184, i.e. inline maths at 1.184em off .article, moving it from 21.78px to 21.312px. This buys exact numeric parity with a number that was itself an accident. It is a 0.47px change on 18px prose that no reader will see, against a 16-PNG baseline refresh — not worth scheduling on its own; take it only as a rider on a change already refreshing those snapshots, and only if the migration record wants the numbers identical.
3. Choose a smaller ratio deliberately, as an improvement to both builds. This is what the review actually points at, and two independent methods land in the same place.
| Target |
Rendered size at 18px prose |
As em off .article |
| Today (KaTeX default) |
21.78px |
1.210em |
| Sphinx as deployed |
21.31px |
1.184em |
| x-heights equal — maths variables sit optically level with the copy |
19.80px |
1.100em |
| What the MathJax config asks for and never gets (0.92 × 118.4%) |
19.61px |
1.089em |
| cap-heights equal — makes maths read distinctly smaller than the copy |
17.30px |
0.961em |
The sensible range is 1.09em to 1.15em, and 1.10em is the value I would put forward: it is where KaTeX_Math's x-height equals Source Sans 3's at the same rendered size, which is the right optical target for inline maths that is mostly lowercase variables, and it lands within 1% of the scale QuantEcon's own config has been asking for. Above about 1.15em the change is too small to be worth a baseline refresh; below about 1.05em the maths starts to read as subordinate to the prose, and cap-height parity at 0.961em is clearly too far.
Two things ride on option 3. Display maths should be left alone — it sits on its own line, so the relational complaint does not apply to it, and Sphinx renders it at the same 118.4% as inline. That means an inline-only selector, and the obvious .katex:not(.katex-display) does not work: KaTeX puts the class on the wrapper, not the maths element (node_modules/katex/dist/katex.css:1207 declares .katex-display > .katex, and on the deployment the display element's own className is empty while its parent's is katex-display), so a :not() on the element matches display maths too and shrinks it along with the rest. The :not() has to sit on the ancestor, as in .article :not(.katex-display) > .katex. And whether quantecon-book-theme takes the same change is part of this decision: matching it there (a chtml: { scale: … } key — the same config that currently mis-names this as svg:) keeps the two builds together through the migration, and not matching it means accepting a divergence that lasts until the Sphinx sites are retired.
Questions for DrDrij
- What window width were you reading at? At desktop width the gap against the Sphinx lectures is 2.2%; below 992px it is 15.1%, because Sphinx drops its root to 16px there and this theme deliberately does not. The answer changes what this is — a parity gap or a design preference.
- Were you comparing side by side against the Sphinx lectures, or judging the mystmd render on its own? If side by side at desktop width, 2.2% is unlikely to be what caught your eye and the container is the more likely culprit — the Exercise block in the review screenshot has a separate and much larger cause in the admonition's own font-size, though note that cannot answer this complaint either, since scaling the container scales copy and maths together and leaves the ratio at exactly 1.210. If on its own, this is a straight design call and option 3 is the live one.
From DrDrij's review of the v2.5.0 build on QuantEcon/lecture-python-programming#363 (item 8a): inline equations read large in relation to the copy around them. That is real and it is measurable — inline maths on the review deployment computes 21.78px inside 18px prose, a ratio of 1.210. But nothing in this theme sets that number, and the Sphinx lectures it replaces are 2.2% away at 1.184, which is MathJax's default rather than a QuantEcon setting. Neither build has ever chosen the size its maths renders at. So what has to be settled is not whether the theme is wrong, but what ratio QuantEcon wants inline maths to sit at against the copy — and that is a choice to take before any CSS is written.
Where 1.21 comes from
The winning rule is KaTeX's own, in the stylesheet the theme self-hosts.
node_modules/katex/dist/katex.css:143(KaTeX 0.16.33) declares.katex { font: normal 1.21em KaTeX_Main, Times New Roman, serif; line-height: 1.2; … }, and the theme adds nothing against it: greppingstyles/andapp/across the v2.5.0 tree forkatexreturns one substantive hit,app/links.ts:2, the import that self-hosts the sheet. The only other.katexrules in the build come from upstream@myst-theme/styles/math.css—.katex-display { margin: 0 !important }and a.katex .eqn-num { opacity: 0 }block — and neither touches size. KaTeX's1.21emtherefore resolves against.article's 18px (styles/quantecon.css:314,font-size: 1.125rem) and lands at 21.78px.Measured, both builds
Chromium at 1440×900, computed styles on the live pages — the review deployment at
https://6a9b93b9108dd4beb6bebadc--epic-agnesi-957267.netlify.app/functionsandhttps://python-programming.quantecon.org/functions.html. Everymjx-containeron the Sphinx page carriesjax="CHTML", and MathJax writes its inline scale onto each one as astyleattribute..katex { font: normal 1.21em … }matchFontHeight, written inline asfont-size: 118.4%font-size: 118.3%)The same glyphs, at two different scales
Canvas
actualBoundingBoxAscentat 100px per em, measured on each live page, with a deliberately unavailable family as a fallback control (italic 44.434 / upright 44.873 — distinct from every row below, so the named faces really did resolve). KaTeX's and MathJax's TeX faces come out metrically identical, because both descend from the same Computer Modern designs. The two builds are drawing the same glyphs; only the scale differs.KaTeX_Mathitalic /MJXTEX-IitalicKaTeX_Main/MJXTEXSource Sans 3 Variable(this theme's prose)Source Sans Pro(Sphinx prose)Scaled to the sizes each build actually renders, that is the optical relationship a reader sees.
So the "maths reads bigger than the copy" character DrDrij describes is present in the Sphinx lectures too, almost identically. Under the recorded stance — parity in idea over engineering parity — that is a reason to treat this as an improvement request, not a reason to close it.
Where the two builds genuinely diverge: narrow viewports
The Sphinx builds step their root size by viewport (16px below 992px, 18px at and above) and reach 18px content that way. This theme sets a flat 18px on
.articleand leaves the root at 16px deliberately, so the reader's own browser font-size preference still applies; the reasoning is written out atstyles/quantecon.css:55-74. The consequence for maths is that the ratio stays ~2% apart at every width but the absolute size does not.Nobody has ever chosen QuantEcon's maths scale
There is no considered QuantEcon value to defer to here, and this is the finding that makes deciding deliberately worth the trouble.
quantecon-book-theme'slayout.html:43-46configures MathJax withsvg: { fontCache: 'global', scale: 0.92, displayAlign: "center" }, while the lecture repo loads the CHTML-only bundle (lectures/_config.yml:79,mathjax_path: https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js). That bundle carries no SVG output jax, there is nochtmlkey anywhere in the book theme's source, and every container in the rendered DOM isjax="CHTML"— so the requested 0.92 scale has never taken effect on any build QuantEcon has shipped, and 118.4% is MathJax's ownmatchFontHeightfilling the vacuum. The only intent on record points at a smaller ratio than either build renders today.That is a defect in its own right and it does not depend on which option below is taken, because the key is mis-named at whatever ratio is chosen. Owner: whoever takes this decision forward files it, against
QuantEcon/quantecon-book-theme— that is where thesvg:key lives and every lecture site inherits it — naming the lecture repo'smathjax_pathas the other half of the pair. Three separate triage passes have now found this and none has filed it.What a change costs
Four of the six visual snapshots contain maths and all four move if a value is set:
intro.pngandsidebar-open.png(inline$e^{i\pi} + 1 = 0$attests/visual/fixture/intro.md:8) andfeatures.pngandhistory-open.png(the display block atfeatures.md:39-41,$r$/$\beta$/$c$in the table at:80-82,$x \in \mathbb{R}$at:90).lists.pngandnotebook.pnghave no maths. That is 16 PNGs acrossdesktop-chrome-{darwin,linux}andmobile-chrome-{darwin,linux}. A change of option 2's size sits well under themaxDiffPixelRatio: 0.01budget attests/visual/theme.spec.ts:34, which is exactly the blind spot #113 records. Any.katexoverride the theme carries also has to be re-verified when KaTeX 0.18's class rename lands (#118).Options
1. Leave it at KaTeX's 1.21. Costs nothing and moves no baselines. For: the two builds are within 2.2% of each other at desktop width, the character is inherent to TeX faces set against a humanist sans, and the Sphinx lectures have shipped this relationship for years with no reported complaint. Against: it is the largest of the plausible values, and it is a default rather than a decision.
2. Match Sphinx's 1.184, i.e. inline maths at
1.184emoff.article, moving it from 21.78px to 21.312px. This buys exact numeric parity with a number that was itself an accident. It is a 0.47px change on 18px prose that no reader will see, against a 16-PNG baseline refresh — not worth scheduling on its own; take it only as a rider on a change already refreshing those snapshots, and only if the migration record wants the numbers identical.3. Choose a smaller ratio deliberately, as an improvement to both builds. This is what the review actually points at, and two independent methods land in the same place.
emoff.articleThe sensible range is 1.09em to 1.15em, and 1.10em is the value I would put forward: it is where
KaTeX_Math's x-height equalsSource Sans 3's at the same rendered size, which is the right optical target for inline maths that is mostly lowercase variables, and it lands within 1% of the scale QuantEcon's own config has been asking for. Above about 1.15em the change is too small to be worth a baseline refresh; below about 1.05em the maths starts to read as subordinate to the prose, and cap-height parity at 0.961em is clearly too far.Two things ride on option 3. Display maths should be left alone — it sits on its own line, so the relational complaint does not apply to it, and Sphinx renders it at the same 118.4% as inline. That means an inline-only selector, and the obvious
.katex:not(.katex-display)does not work: KaTeX puts the class on the wrapper, not the maths element (node_modules/katex/dist/katex.css:1207declares.katex-display > .katex, and on the deployment the display element's ownclassNameis empty while its parent's iskatex-display), so a:not()on the element matches display maths too and shrinks it along with the rest. The:not()has to sit on the ancestor, as in.article :not(.katex-display) > .katex. And whetherquantecon-book-themetakes the same change is part of this decision: matching it there (achtml: { scale: … }key — the same config that currently mis-names this assvg:) keeps the two builds together through the migration, and not matching it means accepting a divergence that lasts until the Sphinx sites are retired.Questions for DrDrij