Skip to content

fix(site[api]) Center declaration controls on the first signature line - #162

Closed
tony wants to merge 1 commit into
mainfrom
declaration-control-alignment
Closed

tony wants to merge 1 commit into
mainfrom
declaration-control-alignment

Conversation

@tony

@tony tony commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

The badges, [source] link and permalink beside a declaration are now level with the center of the signature's first line. On https://libtmux.org/en/ts/latest/reference/server-server-sessions/ the group sat 4.5px above the center of async sessions(): Promise<Selection<Session>>: a formatted native signature pads its code by 0.25rem, and the controls were aligned to the top of that padded box.

The rule

When a header's controls sit beside its code, each control's vertical center equals the center of the signature's first line box. A wrapped signature keeps the controls level with line one, not the block's middle. When the controls wrap onto a row of their own (a phone width, or code too wide to leave room), nothing moves and the controls stay level with each other.

The override lives in site/src/styles/api.css; the vendored gp-sphinx CSS is untouched.

  • The header row aligns first baselines. Native headers (the formatted layouts, TypeScript, Go, Julia, C#, Kotlin, Scala and the other native ports) do so at every width. Python, type and MCP headers do so above the 36rem container breakpoint, where the vendored rule stacks them in a column and keeps its stretch. The group therefore follows line one whatever padding or line height the code has.
  • Inside the group, text controls share a baseline and the badge slot centers on that line. The earlier align-items: center on the group never applied: the vendored baseline rule has equal specificity and loads later.
  • Header height, the code box, wrapping and the stacked layouts do not change. The [source] and # links in the overload headings of Julia methods are inline text on the heading's baseline, not a control group, and are left alone.

The gate

checkDeclarationControlAlignment in site/scripts/check-native-layout.mjs loads these pages at 1440, 768, 500 and 390px, and checks every header on each (up to six):

  • TypeScript Server.sessions (the reported page), Pane.setHook and Client.toString
  • Go Server.NewSessionConnection, a five-line method
  • Python HooksMixin.set_hook, wrapped one parameter per line, and the Server class
  • Julia capture_bytes and C# TmuxBuffers.SetAsync, multi-line native signatures
  • Kotlin Batch, a type header that stays beside its controls at 390px
  • Scala Server.windows, eleven overloads in one header
  • the Rust MCP tool get_pane_info, its tool header and type definition headings

For each header it finds the first glyph's block, takes that block's content-top plus half its used line-height as the first line's center, and requires every control (badges, [source], permalink) to be within 1px of it. Controls that are not beside the code must be level within each of their own rows. The sample fails if it ever stops measuring controls beside code at any of the four widths.

check-dev.mjs runs it after the signature layouts, so it runs in --api-signatures, --reference-layout and the full publication matrix. check-dev-sample.mjs also checks the API probe header at 1440, 768 and 390px in the outer loop. The Kotlin toolbar check, which asserted equal top edges, and checkNativeSignatureGeometry now assert the same center rule. The hosted Scala geometry replay keeps the recorded top-aligned measurement as the rejected case.

Measurements

Largest control offset from the first line's center, in Chromium against a dev server. "n/a" means the controls are on a row of their own at that width, which is unchanged.

Page Width origin/main This branch
TypeScript Server.sessions 1440, 768 4.50px 0.00px
TypeScript Pane.setHook 1440, 768, 500 4.50px 0.00px
TypeScript Client.toString 1440, 768, 500, 390 4.00px 0.00px
Go Server.NewSessionConnection 1440, 768 4.50px 0.00px
Julia capture_bytes 1440, 768 4.50px 0.00px
C# TmuxBuffers.SetAsync 1440, 768 4.50px 0.00px
Scala Server.windows 1440 4.50px 0.00px
Python HooksMixin.set_hook 1440, 768 0.50px 0.00px
Python Server class 1440, 768 0.50px 0.00px
Kotlin Batch 1440, 768, 500, 390 0.50px 0.00px
MCP tool get_pane_info 1440, 768 0.50px 0.00px
MCP type definition heading 1440, 768 1.80px 0.70px
all of the above narrower widths with controls on their own row n/a n/a

The MCP type definition heading is set in the 600-weight face, which Chromium lays out on a 25px line; it passes the 1px tolerance with 0.3px to spare and would need an explicit line height to improve, which would change its header height.

Header height, the code box and the group's box were compared before and after at 1440, 768, 500 and 390px on 15 ports, two pages each, and at 1024, 600 and 320px on seven of those pages. Only the controls' vertical position changed, and only when they sit beside the code. Firefox and WebKit show the same alignment with these rules injected; their group is 0.3px shorter because the badge no longer joins the baseline.

Verification

  • origin/main CSS with the new gate: fails on the first sample, TypeScript one-line formatted method #1 at 1440px: control "method" centre is -4.50px from the first signature line. This branch: 48 header measurements pass, worst beside offset 0.70px.
  • node site/scripts/check-dev.mjs --reference-layout passes, including the modified Kotlin toolbar check, the Scala geometry check and the new sample.
  • pnpm exec vitest run on native-signature-layout, native-signature, api-page-contents, browser-check-port, parameter-permalinks, declaration-body-spacing, inline-reference-appearance and api-fidelity: all pass. Two native-signature cases timed out at the default 5s on a heavily loaded machine and passed on rerun (118 of 118).
  • pnpm run lint has no errors; the warnings are in files this branch does not touch.
  • Not run: check-style-parity.mjs (it needs the assembled _site and the generated gp-sphinx pages, and compares card, header band, signature and field-list styles, none of which this changes), check-dev.mjs --sample, pnpm test, and the full publication audit.

why: The badges, [source] link and permalink beside a declaration were
top-aligned with its code. A formatted native signature pads its code by
0.25rem, so on a one-line declaration such as TypeScript's
Server.sessions the controls sat 4.5px above the line's center. Badges
aligned by their own baseline sat 0.5px high on every other header, and
a heading with a taller line box drifted by more.

what:
- Align the row's first baselines for native headers at every width and
  for Python and MCP headers above the 36rem container breakpoint, so
  controls follow line one of a wrapped signature and ignore the code's
  padding; center the badge slot on the line the text controls share
- Leave the vendored column layout, header height and wrapping as they
  were; a control group on a row of its own is not moved
- Add checkDeclarationControlAlignment to check-native-layout.mjs. It
  loads TypeScript, Go, Python, Julia, C#, Kotlin, Scala and MCP pages at
  1440, 768, 500 and 390px and requires every control beside the code to
  sit within 1px of the center of the first signature line, and
  controls that wrap onto their own rows to be level within each row.
  check-dev.mjs runs it with the signature layouts and the sample loop
  checks the API probe header
- Replace the top-edge assertion in checkNativeSignatureGeometry with a
  center assertion, and replay the observed hosted Scala geometry as the
  rejected case

Largest control offset from the first line's center, origin/main then
this change, measured in Chromium against the dev server:
- TypeScript, Go, Julia and C# formatted methods: 4.50px, then 0.00px at
  1440 and 768px; TypeScript client.toString at 390px: 4.00px, then 0.00px
- Python method and class, Kotlin type: 0.50px, then 0.00px
- MCP tool header: 0.50px, then 0.00px; its type definition headings,
  whose 600-weight face makes a 25px line: 1.80px, then 0.70px
- Header heights, code boxes and the stacked layouts are unchanged
@tony

tony commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

Folded into #157, which now carries every fix from the 2026-10-18 review on one branch so they share one CI run, preview and deploy. This commit is on that branch unchanged. Discussion and evidence stay here.

@tony tony closed this Oct 18, 2026
@tony
tony deployed to docs-preview October 18, 2026 12:32 — with GitHub Actions Active
@tony
tony deployed to docs-preview-cleanup October 18, 2026 13:25 — with GitHub Actions Active

This branch was successfully deployed

2 active deployments
docs-preview-cleanup — ef25f84f Deployed Oct 18, 2026 by tony via cleanup #146
docs-preview — ef25f84f Deployed Oct 18, 2026 by tony via publish-preview / publish #818
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