From 7610f598891ecd07c5ff463c0cde94d5756af8f1 Mon Sep 17 00:00:00 2001 From: macanderson Date: Tue, 21 Jul 2026 18:16:37 -0700 Subject: [PATCH] fix(site): stop docs tables overflowing and showing through sticky bars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The protocol-surface conformance tables were unreadable at tablet and phone widths: the last column was cut off with no way to scroll to it, and table rows stayed visible through the two sticky bars as you scrolled, reading as a ghosted second table over the real one. Three causes, all in the docs' shared CSS: * `html { zoom: 1.07 }` was global. Media queries are evaluated against the unzoomed viewport, so every breakpoint fired while the layout actually had 1/1.07 of that width to work with. At 768px the tables overflowed by up to 59px and escaped the article, where the docs grid's `overflow-x-clip` silently cut them off. The zoom is only wanted for the px-authored marketing page, so it moves onto `.marketing-page` — the marketing layout renders pixel-identically (verified by screenshot hash at 1440 and 1024), and the docs go back to the natural scale fumadocs is designed around. * Long identifiers like `contextgraph-host::wire::versions_compatible` are one unbreakable token, so they set the cell's min-content width and pushed the table past the viewport on narrow screens even without the zoom. Code inside table cells may now break mid-token. * Fumadocs ships the docs header and the TOC popover bar at 80% alpha over a backdrop blur. Against this near-monochrome palette the rows underneath stayed legible through them. Both bars are now opaque. Verified on the production build at 320–1512px in both colour schemes: table overflow and article escape are 0 at every width (previously up to 194px at 320px), and the marketing page is byte-identical. --- site/src/app/globals.css | 31 +++++++++++++++++++++++-------- site/src/app/marketing.css | 14 ++++++++++++++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/site/src/app/globals.css b/site/src/app/globals.css index 375bcb0..d0646d1 100644 --- a/site/src/app/globals.css +++ b/site/src/app/globals.css @@ -96,14 +96,6 @@ background: var(--background); color-scheme: light; text-rendering: optimizeLegibility; - /* - * Page-level zoom. The marketing page is authored almost entirely in px - * and the docs in rem, so a root font-size bump would only scale the docs. - * `zoom` scales both layouts uniformly, exactly like a browser zoom, and - * unlike `transform: scale` it keeps sticky headers and document flow intact. - * Tune this single value to taste. - */ - zoom: 1.07; } html.dark { @@ -217,6 +209,29 @@ vertical-align: top; } + /* + * Long identifiers (`contextgraph-host::wire::versions_compatible`) are a + * single unbreakable token, so they set the cell's min-content width and + * push the whole table past the viewport on narrow screens — where the + * docs grid's `overflow-x-clip` silently cuts the last column off. Let + * code, and only code, break mid-token inside table cells. + */ + .prose :where(td, th) code { + overflow-wrap: anywhere; + } + + /* + * The docs sticky chrome must be opaque. Fumadocs ships both bars at 80% + * alpha over a backdrop blur; against this near-monochrome palette the + * table rows scrolling underneath stay legible through them, so the page + * reads as a ghosted second table overlapping the real one. + */ + #nd-docs-layout #nd-subnav, + #nd-docs-layout [data-toc-popover] > header { + background: var(--background); + backdrop-filter: none; + } + .prose :where(code):not(:where(pre *, .not-prose *)) { border: 1px solid var(--border); border-radius: 0.25rem; diff --git a/site/src/app/marketing.css b/site/src/app/marketing.css index df40c3e..4f71f80 100644 --- a/site/src/app/marketing.css +++ b/site/src/app/marketing.css @@ -12,6 +12,20 @@ } .marketing-page { + /* + * Page-level zoom, scoped to the marketing layout. This page is authored + * almost entirely in px, so a root font-size bump would not scale it. + * `zoom` scales it uniformly, exactly like a browser zoom, and unlike + * `transform: scale` it keeps sticky headers and document flow intact. + * Tune this single value to taste. + * + * Deliberately NOT on `html`: media queries are evaluated against the + * unzoomed viewport, so a zoomed root makes every breakpoint fire while + * the layout actually has 1/zoom of that width to work with. The docs + * layout is responsive and breaks under that mismatch — its tables + * overflow and get clipped by the layout grid's `overflow-x-clip`. + */ + zoom: 1.07; margin: 0; background: var(--paper); color: var(--ink);