feat(docs-site): widen the content column and add a mermaid lightbox - #577
Merged
Conversation
The documentation site set its prose at Starlight's default 45rem and drew every mermaid diagram at that width. Fifteen of the forty-two pages carry a diagram and all of them are architecture pages, where the diagram is the page's point — and at column width the large ones are unreadable. Two changes, one file each plus the styles: - `--sl-content-width` goes to 50rem. It is a max-width, so it binds only where there is room: measured at 1440 the column gains 52px and at 1920 the full 80px, while at 1280 and below the pane is already space-constrained and nothing moves. - Every diagram gets a magnifier button opening it in a `<dialog>` at 92vw x 88vh, with wheel-zoom about the cursor and drag-pan for the graphs that do not fit even there. One dialog is created lazily and reused; the diagram's SVG is cloned into it with mermaid's width, height and inline max-width cleared so the viewBox fits it to the box. The wrapper the button hangs off is emitted by the remark transform rather than injected in the browser, and that is load-bearing: the redraw that follows every theme toggle reassigns the `<pre>`'s text content, so a button inside it is destroyed. Verified with a control pair — a marker in the `<pre>` does not survive a toggle, one in the wrapper does. Two things the browser corrected: a modal dialog is centred by the UA's `margin: auto`, which Starlight's reset zeroes, so the dialog opened against the top-left until the margin was restored explicitly; and the clone must be found through `pre.mermaid svg`, since the figure also contains the magnifier's own icon and a bare `figure svg` picked the diagram only by document order. No new dependency, no change to how diagrams are authored, no per-diagram configuration.
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.
Two dogfooding findings on the documentation site: the prose column was at Starlight's default
45rem, and every mermaid diagram was drawn at that width. Fifteen of the forty-two pages carry a
diagram and all of them are architecture pages, where the diagram is the page's point — at
column width the large ones are unreadable.
What changed
--sl-content-width: 50rem, on the bare:root. Measured at a fixed viewport, toggling onlythe token:
It is a ceiling, so below ~1400 it does nothing — the pane is already space-constrained by the
sidebar and the table of contents and never reaches even the old value. That is stated rather than
hidden; see "Found, not fixed". No overlap and no horizontal body scroll at 1280, 1024 or 390, each
measured rather than eyeballed.
A magnifier on every diagram, opening it in a shared
<dialog>at 92vw × 88vh with wheel-zoomabout the cursor and drag-pan, clamped to
[1, 8]and reset to fit on every open. The SVG iscloned with mermaid's
width/heightattributes and inlinemax-width: Npxcleared, so theviewBoxfits it while preserving the ratio. Themed only with Starlight tokens — no hex.No new dependency, no change to how diagrams are authored, no per-diagram configuration, no
frontmatter touched.
The constraint that shaped it
Head.astro'sdraw()reassignsnode.textContenton every redraw, and it redraws on everytheme toggle — so a button injected inside the
<pre>is destroyed.pre.mermaidalso scrollshorizontally, so an absolutely-positioned child would slide out of view on exactly the wide
diagrams that need the button most. The wrapper is therefore emitted at build time by the remark
transform, not injected in the browser.
Proven load-bearing with a control pair — identical markers, one in each place, across a real
toggle:
{ survivedInPre: false, survivedInFigure: true }.Two things the browser corrected
<dialog>is centred by the UA'smargin: auto, and Starlight's reset zeroes margins on everything. Measuredx: 0, y: 0where58, 60was expected. Fixed with an explicitmargin: auto.figure.querySelector("svg")picked the diagram only by document order — the figure alsocontains the magnifier's own inline-SVG icon, and the bare selector was correct purely because
the button is appended after the
<pre>. Now scoped topre.mermaid svg. Prepending thebutton flips the bare selector to "the button icon" and leaves the scoped one on the diagram.
Test plan
No automated coverage:
docs-sitehas no unit or e2e suite, and standing up a browser harness forthe documentation site is a larger decision than this change. Everything below was verified
interactively in chromium against the dev server.
matchesFocusVisible: true,opacity: 1:modal,1325×880at viewport1440×1000(= 92vw × 88vh)focusReturnedTo: mermaid-zoom,isTheMagnifier: true738×87→1275×151, 1.73×, fits stagetranslate(-271.299px, 0px) scale(1.82212)(-100, -40)→translate(-371.299px, -40px)scale(1),translate(0,0); 40 notches in →scale(8)prefers-reduced-motion: reduceanimationName: "none"; otherwise0.12shasTouch,isMobile)hover: nonematches,opacity: 1without hoveringMutation check. The wheel listener's
{ passive: false }is the one guard whose absence issilent. Committed first, then mutated to
{ passive: true }and re-measured in the browser:defaultPreventedtrue with it, false without. Reverted; tree confirmed clean.Gates
Only
docs-site/was touched. It is its own pnpm workspace root, not afrontend/*member, shipsin no Python package and no image, and the browser suites drive
frontend/apponly — so theacceptance set is the docs group plus every repo gate that actually scans
docs-site.bash scripts/check.sh docs— exit 0 (build; projection deterministic, 42 pages; 3682internal links across 43 pages all resolve)
node --test tests/scripts/{docs_sidebar,docs_links,cooldown}.test.mjs— exit 0, 20 passuv run pytest tests/architecture/test_tracked_file_sizes.py -q— exit 0Not run:
python,frontend,generated,browser— nothing in this diff is reachable from them.The build's two warnings (deprecated
markdown.remarkPlugins, sitemap's missingsite) arepre-existing on
mainand unrelated.Found, not fixed
on a 13–14" laptop, the lever is the sidebar/ToC widths or the pane's gutters — a real layout
change, deliberately out of scope here.
visionset.cssstatesits values are shared verbatim across the family; the header now records this token as a
deliberate exception rather than drift.
.playwright-mcp/is not in.gitignore. The Playwright MCP tooling writes snapshots andconsole logs into the repo root it runs from. Cleaned up by hand here; one ignore line would
settle it permanently.
markdown.remarkPlugins— the keyastro.config.mjsuses to register themermaid transform — wants moving to
unified({...})from@astrojs/markdown-remark.