feat(styles): 16px code and callouts, solid resting underline, AA footer contrast - #238
feat(styles): 16px code and callouts, solid resting underline, AA footer contrast#238quantecon-services wants to merge 3 commits into
Conversation
…ter contrast Code blocks render their source at 16px / 20px instead of the 13px / 17px JupyterLab default that thebe-core.css applied to every <pre>. The value is set on the JupyterLab variables, scoped to .article, so the source block, Jupyter's live-compute output and thebe's derived spacing follow it together; stored outputs take their own 16px / 20px rule. The frame is unchanged. Admonition, exercise, proof and dropdown bodies step down to 16px, root-relative so nested callouts do not compound, and their titles take the container's size. Content links keep a resting underline and it is now solid on both .link and .hover-link, removing the thumbnail-driven dotted/solid split. The link colour is 2.02:1 (light) and 1.49:1 (dark) against the body text, so colour alone cannot mark a link and the underline cannot be hover-only. The footer's text and links clear WCAG AA once its 70% opacity is composited: #3b3b3b and #00436f in light mode, #b5b5b5 for dark text. The colour utilities come off the element so the stylesheet is the only source. Computed-style tests cover each change; a nested callout is added to the fixture. Docs gain a typography page, and CONTRIBUTING records the two new deliberate divergences from the lecture builds. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K8u2d3ZQEcz8D6P7Zuyugn
|
/update-snapshots Re-captures every Generated by Claude Code |
|
|
@DrDrij was just updating the project issues and it was suggested to throw this together. You can take or leave it as you see fit. |
|
🎭 Refreshed visual baselines in 8c557bd:
|
🎭 Visual regression resultsDetails
Skipped testsmobile-chrome › theme.spec.ts › QuantEcon theme — visual regression › without JavaScript › drawer-opens-without-javascript |
|
A correction and one ask. Correction. My Ask. The refreshed baselines are in 8c557bd, pushed by the workflow. GitHub created the CI and preview runs for that commit in the "action required" state (the triggering actor is Generated by Claude Code |
There was a problem hiding this comment.
🔵 Needs a closer look
The changes are visual/accessibility CSS adjustments whose correctness depends on rendered contrast math, cascade/layer interactions, and a manual multi-platform snapshot-baseline refresh that cannot be fully verified without a human render.
Pull request overview
This PR implements four accepted decisions from the v2.5.0 design review (#187), grouped onto one branch so the overlapping visual-snapshot set is refreshed once. It resizes code blocks and callout bodies against the 18px prose, unifies content-link underlines to a solid resting line, and darkens the site footer's text/link colours so their composited (opacity-faded) contrast clears WCAG AA in both modes. All changes live in styles/quantecon.css (plus a one-line component cleanup in SiteFooter.tsx), with matching docs, CHANGELOG, and computed-style tests.
Changes:
- Code source blocks and stored outputs render at 16px/20px (via the
--jp-code-*JupyterLab variables scoped to.article, plus a direct rule for.myst-jp-safe-output-text); callout bodies/titles step down to 16px, root-relative so nested callouts don't compound. .linkand.hover-linkget a solidtext-decoration-line/-styleat rest, removing the thumbnail-driven dotted/solid split.- Footer colours moved off
SiteFooter's utilities into CSS: light text#3b3b3b, light link#00436f, dark text#b5b5b5, so the composited-at-70%-opacity contrast meets AA.
File summaries
| File | Description |
|---|---|
| styles/quantecon.css | Core change: adds CODE BLOCKS/CALLOUTS blocks, solid resting underline, footer colour/dark-mode rules with contrast rationale. |
| app/components/SiteFooter.tsx | Removes footer colour/opacity utilities so the stylesheet is the sole colour source in both modes. |
| tests/visual/theme.spec.ts | Adds four computed-style tests (footer-contrast, code-block-size, callout-size, link-underline-solid). |
| tests/visual/fixture/features.md | Adds an exercise containing a nested note to exercise the no-compounding size rule. |
| docs/typography.md | New page documenting content size, code blocks, callouts, and links. |
| docs/layout.md | Adds a footer paragraph on size/opacity and the AA-driven colour divergence. |
| docs/index.md | Adds the typography row to the docs table. |
| docs/code-highlighting.md | Adds a pointer to the new typography page for size/frame. |
| CONTRIBUTING.md | Records two new deliberate WCAG divergences; drops the now-resolved #201 pointer. |
| CHANGELOG.md | Adds Changed/Fixed entries under ## [Unreleased]. |
Review details
- Files reviewed: 10/23 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Dropping the resolved footer pointer from the parenthetical joined the next sentence onto the same line; wrap it back to the width the rest of the section uses. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K8u2d3ZQEcz8D6P7Zuyugn
|
Status, closing the round above.
Generated by Claude Code |
The combined CSS PR from the v2.5.0 design review (#187): the four items whose decisions are in, on one branch so the snapshot set is refreshed once. Nothing here waits on design input; what does is listed at the end.
What changes
<pre>was 13px / 17px against 18px prose: JupyterLab's default, applied bythebe-core.css'stt, code, kbd, samp, preelement rule, which lands on the<pre>itself and outranks thetext-sminherited from the.myst-codewrapper. The value goes on the same variables (--jp-code-font-size,--jp-code-line-height), set on.articlerather than:rootso it beats thebe's:rootdeclaration regardless of stylesheet order, and every consumer of the variable follows: the source block, the output Jupyter renders under live compute, and the twocalc()s thebe derives from it. That is the vector Non-executable code blocks get no frame, and every code block renders 13px against 18px prose #184 records rather than the narrowpreselector How code blocks should be framed and sized against 18px prose #177's text recommends: the design decision is the size, and the narrow selector would have left a cell's source and output at different sizes and made code resize when live compute is switched on. Stored outputs (.myst-jp-safe-output-text,font-mono text-sm) get their own 16px / 20px rule. Frame unchanged, per option 4..myst-admonition,.myst-exercise,.myst-proofand.myst-dropdownat1rem, root-relative so a note nested in an exercise does not step down twice, and flat where the Sphinx rule falls to 14.4px below 992px. Titles take the container's size: exercise and proof headers already inherit (text-mdis not a Tailwind class); admonition and dropdown headers carriedtext-lgand now take1em. Weight untouched;.myst-asideuntouched..linkand.hover-link(Whether content links keep a resting underline or underline only on hover #176, decided 2026-09-10: keep the resting underline).text-decoration-line: underline; text-decoration-style: solidon both, which also removes the dotted/solid split that followed whether a target page had a thumbnail. Colours unchanged;:visitedstill unstyled, its dark value waiting on Which dark palette this theme ships: the pre-0.18.0 greys it has, the book theme's navy-charcoal, or its own #237.#444was 4.17:1 and links#0072bc3.01:1 on white; dark text#a6a6a6was 3.92:1 on#222(thedark:text-qetext-dark-mutedutility won over the footer rule, confirmed in the compiled bundle). Now#3b3b3b(4.54:1),#00436f(4.55:1) and#b5b5b5(4.55:1); the dark link#93c5fd(5.04:1) is unchanged, as are the fade, the badge and the 5px rule. The colour utilities come off theSiteFooterelement so the stylesheet is the only source in both modes.Tests
Four computed-style assertions, so each change is guarded by a number rather than by pixels:
code-block-size: 16px / 20px on a plain fence, an executable cell and its stored output.callout-size: 18px prose; 16px on admonition, exercise and proof bodies and headers, and on the note nested in the exercise (new fixture content infeatures.md).link-underline-solid:underline/solidin QuantEcon blue on a.hover-linkcross-reference and a.link.footer-contrast: composites the computed colours at the computed opacity on the nearest painted ancestor and asserts at least 4.5:1 for text and link, light and dark.npm run compile,npm run test:unit(59 pass) and the CI comment-rule grep pass locally, and all four new tests pass on CI. On the first commit the visual job failed its snapshot comparisons, as a change that moves every page should: 12 of them (intro, features, lists, notebook, history-open and rtl on both viewports; sidebar-open stayed within budget). An earlier version of this paragraph said the snapshots passed under the 1% budget; that was a misreading of the local run's summary and is withdrawn.Baselines
Every snapshot name moves:
features,history-openandnotebook(code size);features,history-openandlists(callouts);intro,features,history-open,sidebar-openandrtl(links); and all of them for the footer.-linux: refreshed by the/update-snapshotsworkflow in 8c557bd (13 files, both viewports). CI is green on that set and on the current head.-darwin: needsTHEME_TEMPLATE="$PWD/.deploy/quantecon-theme" npx playwright test --update-snapshots=allon a Mac.Docs
New
docs/typography.md(content size, code blocks, callouts, links), a row indocs/index.md, a footer paragraph indocs/layout.md, a pointer fromdocs/code-highlighting.md, and two entries in CONTRIBUTING's list of deliberate divergences from the lecture builds. CHANGELOG under Unreleased.Not in this PR
#0072bcis proposed on How code blocks should be framed and sized against 18px prose #177 and waits on DrDrij.font-monostack while the source block resolves to thebe's, so the two can still differ in face on Linux; the decision covered size only.🤖 Generated with Claude Code
https://claude.ai/code/session_01K8u2d3ZQEcz8D6P7Zuyugn