Skip to content

Even out the docs chrome: rails, headings, anchors, focus, surfaces - #268

Merged
fstubner merged 1 commit into
mainfrom
fix/site-chrome-polish
Aug 28, 2026
Merged

fstubner merged 1 commit into
mainfrom
fix/site-chrome-polish

Conversation

@fstubner

Copy link
Copy Markdown
Owner

Seven of the open acceptance items. Each measured on a running build before and after — the Browser pane is not displayed in my session, so these come from a headless Chrome at real viewport sizes rather than from eyeballing.

Page padding was uneven

The frame is centred exactly — 25/25 at 1280px, 143/143 at 1920px. The asymmetry was inside the rails: the section rail insets its text by a fluid 35–50px, the contents rail used a flat 16px.

left text column right text column
before 84px from viewport 40px from viewport
after 37.86px rail inset 37.86px rail inset

The contents rail mirrors the section rail's insets now, and widens 13rem → 15rem so its text column does not pay for the padding.

--netscli-sidebar-rail-inset moves to :root. It was declared twice on .sidebar-content alone — 2.1rem in 02, 2.2rem in 14 — the same token with drifted values, which is why the other rail could not read it.

The left nav's hover highlight was inset from the active one

Only the current link was pulled onto the rail:

before   Overview      borderX=91.9  textX=107.5   margin-start=0
         Installation  borderX=82.9  textX=107.5   margin-start=-9px   <- current
after    every link    borderX=82.9  textX=107.5   margin-start=-9px

The border was the intended difference; the box was not. Only the border colour marks the current page now.

Headings were sized for a poster

Starlight's defaults gave h1 42px and h2 35px against 16px body text — an h2 more than twice the paragraph beside it and nearly the size of the h1 above it. A ~1.25 scale: 34 / 26 / 21.

Anchor links jumped, and landed behind the header

The docs never load global.css, so scroll-behavior was auto and every heading had scroll-margin-top: 0 under a 60px sticky header. Smooth now (with a prefers-reduced-motion opt-out), headings clear the chrome by 80px.

The theme selector had no focus indicator

:focus-within was grouped with :hover, so tabbing to it nudged the border tint and removed the background. The select has appearance: none and no border, so its own ring had nothing to draw around. It gets a real 2px accent outline.

Its dropdown rows were rgba(17,17,17,.92) — the platform will not use a translucent colour for option, so they fell back to the browser default. Opaque values per theme.

Search button vs menu toggle

Side by side in the narrow header, painted differently — rgba(17,22,29,.9) under a gradient vs a flat rgba(255,255,255,.035). One read recessed, the other flat. Both use the hairline token now, hover included, in both themes.

Breadcrumb chevrons sat low

Their line boxes are centred correctly — label, separator and current page all centre at 81px. But the chevron glyph is drawn mid-em-box while the words beside it sit on the baseline. A 1px optical lift, not a layout change.

Housekeeping

30-toc-under-hero.css had held nothing about the ToC since #261 reverted that experiment — one unrelated rule under a name describing none of it. Renamed to 30-scroll-and-search-offline.css and given the scroll rules.

CSS shadowing budget 42 → 26. The edits added five dead declarations; a prune pass removed 21. All seven fixes re-measured after the prune, unchanged.

Verification

astro check 0 errors across 54 files · a11y 0 violations in both themes · check:css 26/26 · check:changelog · file-size guard · no horizontal overflow at 500px or 1440px (scrollWidth == viewport on landing, docs index, and a docs page).

Seven of the open acceptance items, each measured before and after against a
running build rather than eyeballed.

Page padding was uneven. The frame is centred exactly -- 25/25 at 1280,
143/143 at 1920 -- so the asymmetry was inside the rails, not the frame: the
section rail insets its text by a fluid 35-50px, the contents rail used a
flat 16px. So the left text column started 84px from the viewport edge and
the right one ended 40px from it. The contents rail now mirrors the section
rail's insets exactly (37.86/37.86 at 1280, 50.4/50.4 at 1920) and widens
from 13rem to 15rem so its text column does not pay for the padding.

`--netscli-sidebar-rail-inset` moves to :root. It was declared twice on
`.sidebar-content` alone, 2.1rem in 02 and 2.2rem in 14 -- the same token
with drifted values, which is why the other rail could not read it.

The left nav's hover highlight was inset from the active one. Only the
current link was pulled onto the rail, so its box started at x=82.9 and every
other link's at x=91.9, with text aligned at 107.5 throughout. The border was
the intended difference; the box was not. All links share the geometry now,
so only the border colour marks the current page.

Headings were sized for a poster. Starlight's defaults put h1 at 42px and h2
at 35px against 16px body text -- an h2 more than twice the paragraph beside
it and nearly the size of the h1 above it. A ~1.25 scale gives 34/26/21.

Anchor links jumped and landed behind the header. The docs never loaded
global.css, so `scroll-behavior` was `auto` and every heading had
`scroll-margin-top: 0` under a 60px sticky header. Smooth now, with a
reduced-motion opt-out, and headings clear the chrome by 80px.

The theme selector had no focus indicator. `:focus-within` was grouped with
`:hover`, so tabbing to it changed the border tint slightly and *removed* the
background; the <select> has `appearance: none` and no border, so its own
ring had nothing to draw. It gets a real 2px accent outline. Its dropdown
rows were `rgba(17,17,17,.92)` -- the platform will not use a translucent
colour for them, so they fell back to browser default white-on-black. Opaque
values per theme.

The search button and the menu toggle sit side by side in the narrow header
and were painted differently -- one recessed, one flat. Both are
`rgba(255,255,255,.035)` on the hairline token now, hover included.

The breadcrumb chevrons sat low. Their line boxes are centred correctly and
measured identical, but `›` is drawn mid-em-box while the words beside it sit
on the baseline. A 1px optical lift.

Renames 30-toc-under-hero.css, which had held nothing about the ToC since
#261 reverted that experiment, to 30-scroll-and-search-offline.css and gives
it the scroll rules.

CSS shadowing budget 42 -> 26: the edits added five dead declarations and a
prune pass removed 21. astro check 0 errors across 54 files, a11y 0
violations in both themes, no horizontal overflow at 500px or 1440px.
@github-actions

Copy link
Copy Markdown
Contributor

Site preview: https://pr-268.netscli-site-preview.pages.dev

Built from d523598 with NETSCLI_PREVIEW=1 — noindex, and analytics disabled so it does not report into netscli.com's numbers.

Production is unaffected: netscli.com is served from GitHub Pages via pages.yml, which is manual-only.

@fstubner
fstubner merged commit 7d73b7b into main Aug 28, 2026
14 checks passed
@fstubner
fstubner deleted the fix/site-chrome-polish branch August 28, 2026 18:59
fstubner added a commit that referenced this pull request Aug 28, 2026
Both this branch and #268 ran the CSS prune, so they disagreed on blank
lines in two files and on the shadowing budget. The whitespace hunks take
main's shape; the budget is a measurement, so it is re-counted here rather
than picked from either side.

All three search fixes re-measured on the rebased build -- cancel level with
the input, clear 8px inside the field's trailing edge, drawer ending 37px
above the viewport and scrolling internally -- and #268's rail alignment
still holds at 42.66px on both sides.
fstubner added a commit that referenced this pull request Aug 28, 2026
…ield (#272)

* Let the mobile search dialog fill the screen, and put Cancel by the field

Three faults, all measured at 500x708 with results on screen.

The results stopped 151px above the bottom. `#starlight__search` carried
`max-height: calc(100vh - 9.5rem)` and the drawer
`max-height: calc(100vh - 15rem)` -- 152px and 240px reserved for chrome that
does not exist at this size, where the dialog is inset 9px and runs nearly
the full height. The drawer's bottom landed at 557 in a 708 viewport.

Replacing those with `100%` was not the fix: no ancestor has a definite
height for a percentage to resolve against, so the drawer took its content
height and pushed 1253px past the viewport, scrolling the page instead of
itself. The chain is what mattered. `#starlight__search` was already a flex
column, but the drawer is two levels below it -- `.pagefind-ui` and
`.pagefind-ui__form` sit between, both `display: block` with `min-height:
auto`, so neither would shrink below its content. Both are flex columns with
`min-height: 0` now, and the form grew from `flex: 0 0 auto` (right when it
held only the input) to `1 1 auto`. Drawer bottom 671, 37px of frame below
it, scrolling inside itself.

Cancel sat level with the middle of the results. Starlight lays the frame out
as `"search close" / "drawer drawer"` and 23, 24 and 28 each pinned the
button to row 1 with `align-self: center`. That row holds the whole Pagefind
UI, not just the input, so it is ~590px tall and centring put Cancel at
y=287. `start` in all three.

The clear control floated 83px short of the field's trailing edge. Pinned to
it, 8px in.

`align-content: start` on the frame is what stopped the rows growing at all.
It had no stated reason; the empty-state height it appeared to guard is set
directly by the `min-height` rules in 06, 23 and 28, and both the empty and
no-match states were checked after changing it -- the drawer stays compact
when it has little to show and fills only when it has results.

Desktop is unaffected: 1440x900 gives drawer 145-677 in a 748 viewport,
scrolling internally, as before.

One thing not fixed: Cancel's box is 18px lower than centring it against the
input would put it. Its own margins are 0 and `align-self` computes to
`start`, so the offset is coming from somewhere I did not chase. It is beside
the field rather than beside the results, which was the fault.

CSS shadowing budget 42 -> 25. astro check 0 errors, a11y 0 violations.

* Rebase onto main: budget 24, measured after the merge

Both this branch and #268 ran the CSS prune, so they disagreed on blank
lines in two files and on the shadowing budget. The whitespace hunks take
main's shape; the budget is a measurement, so it is re-counted here rather
than picked from either side.

All three search fixes re-measured on the rebased build -- cancel level with
the input, clear 8px inside the field's trailing edge, drawer ending 37px
above the viewport and scrolling internally -- and #268's rail alignment
still holds at 42.66px on both sides.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant