refactor(website): finish the json-render rename; generalise style contracts - #926
Merged
Merged
Conversation
…ntracts Two follow-ups from #923. json-render on marketing surfaces --------------------------------- #923 renamed the docs picker label but deliberately left the marketing surfaces. They now agree: the homepage FeatureBlock eyebrow, the footer link, and the three solutions architecture layers all read json-render. Two hazards this surfaced: - The footer derives cta_id from the visible label, so renaming the link would have silently split PostHog's footer_render into a new footer_json_render series. trackFooterCta now takes an optional explicit CtaId and the render link pins the original. - The solutions page maps library name to href through a Record<string, string>. Renaming the data without the key returns undefined and renders the card unlinked — no error, no type failure. solutions-links.spec.ts asserts every layer resolves; mutation-tested by renaming one side only. Style contracts --------------- docs-sidebar-styles.spec.ts guarded two CSS declarations whose loss is invisible to jsdom, but it was a one-off with an inline parser. It is replaced by style-contract.ts plus a registry in style-contracts.spec.ts, so adding a guard is one entry rather than a new file. Seeded with four live rules, each mutation-tested by deleting the declaration and by renaming the selector wholesale: - .docs-sidebar-lib-item-text flex column (the #892 collision) - .docs-sidebar-lib-menu max-height + overflow-y - .docs-control-plane position sticky + align-self - [data-control-plane-pane] overflow-y Writing the registry found a bug in the extracted parser: a CSS comment above a rule lands inside the selector capture, so the exact match never fires and a guarded rule reports as missing. Comments are stripped first. Also removes the DocsSidebar wrapper and its .docs-sidebar rule, dead since #892 moved the docs nav into the control plane — only DocsNavigation is imported, and the sole class usage was inside the dead component. Its comment documented the same align-self hazard now held by the .docs-control-plane contract. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
blove
enabled auto-merge (squash)
September 1, 2026 05:37
Contributor
blove
added a commit
that referenced
this pull request
Sep 1, 2026
PR #863 deleted the global `.shiki` rules from docs.css on the finding that zero elements matched. That was true of docs and blog — rehype-pretty-code writes its background inline and never emits a `.shiki` class — but two TSX call sites highlight with Shiki's `codeToHtml` directly, which does: - components/landing/HighlightedCode.tsx (homepage Code tabs, /langgraph, /render, /chat) - components/solutions/SolutionCodeBlock.tsx (every /solutions/* page) Those <pre> elements lost their padding. The dark theme background rides inline on the <pre>, while the landing override put its 16px 20px on the wrapper <div> (which carries `shiki` too) — outside the dark box. The result was a light gutter with the code flush against the dark edges. Restores the padding as a `pre.shiki` base rule in global.css, and moves the landing override's padding off the wrapper onto `> pre.shiki`. The selector is pre-scoped deliberately: both call sites also put the class on a wrapper div, where padding lands outside the surface. SolutionCodeBlock's comment claimed Shiki emits its own padding — that wrong premise is what made the deletion look safe, so it is corrected too. Guarded in two halves, since neither is sufficient alone. The CSS half is a style contract (#926's registry — this is precisely the "comment explaining why a declaration must not be removed" that it asks for), mutation-tested by deleting the declaration and by renaming the selector. The markup half lives in HighlightedCode.spec.tsx: that Shiki still emits a `pre.shiki` carrying an inline background and no padding of its own, so the contract keeps guarding a rule something actually matches. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
blove
added a commit
that referenced
this pull request
Sep 1, 2026
PR #863 deleted the global `.shiki` rules from docs.css on the finding that zero elements matched. That was true of docs and blog — rehype-pretty-code writes its background inline and never emits a `.shiki` class — but two TSX call sites highlight with Shiki's `codeToHtml` directly, which does: - components/landing/HighlightedCode.tsx (homepage Code tabs, /langgraph, /render, /chat) - components/solutions/SolutionCodeBlock.tsx (every /solutions/* page) Those <pre> elements lost their padding. The dark theme background rides inline on the <pre>, while the landing override put its 16px 20px on the wrapper <div> (which carries `shiki` too) — outside the dark box. The result was a light gutter with the code flush against the dark edges. Restores the padding as a `pre.shiki` base rule in global.css, and moves the landing override's padding off the wrapper onto `> pre.shiki`. The selector is pre-scoped deliberately: both call sites also put the class on a wrapper div, where padding lands outside the surface. SolutionCodeBlock's comment claimed Shiki emits its own padding — that wrong premise is what made the deletion look safe, so it is corrected too. Guarded in two halves, since neither is sufficient alone. The CSS half is a style contract (#926's registry — this is precisely the "comment explaining why a declaration must not be removed" that it asks for), mutation-tested by deleting the declaration and by renaming the selector. The markup half lives in HighlightedCode.spec.tsx: that Shiki still emits a `pre.shiki` carrying an inline background and no padding of its own, so the contract keeps guarding a rule something actually matches. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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 follow-ups from #923.
1 — json-render on marketing surfaces
#923 renamed the docs picker but deliberately left marketing alone. They now agree: the homepage FeatureBlock eyebrow, the footer link, and the three solutions architecture layers all read
json-render. Verified in the browser — no bare "Render" remains on/,/solutions/*, or the footer.Two hazards this surfaced, both silent:
cta_idfrom the visible label. Renaming the link would have turnedfooter_renderintofooter_json_renderand split the PostHog series with no error.trackFooterCtanow takes an optional explicitCtaIdand the render link pins the original id, so the analytics series stays continuous while the text changes.Record<string, string>. Renaming the data without the key returnsundefinedand renders the card unlinked — no error, no type failure, nothing visible in review.solutions-links.spec.tsasserts every layer resolves; mutation-tested by renaming one side only, and it correctly reports[ 'json-render', 'json-render', 'json-render' ]unresolved.2 — Generalising the style contract
docs-sidebar-styles.spec.tsguarded two CSS declarations jsdom can't see, but it was a one-off with an inline parser. Replaced bystyle-contract.tsplus a registry instyle-contracts.spec.ts, so adding a guard is one entry rather than a new file — with a documented bar for what belongs (the tell is "you wrote a CSS comment explaining why a declaration must not be removed") and an explicit warning against adding ordinary styling, since a contract that fires on every design tweak teaches people to delete contracts.Seeded with four live rules:
.docs-sidebar-lib-item-text.docs-sidebar-lib-menu.docs-control-plane[data-control-plane-pane]Every contract was mutation-tested by deleting the declaration and by renaming the selector wholesale. The first attempt at the rename mutation was invalid —
.docs-sidebar-lib-menuhas two rule blocks and I renamed only one, so the contract stayed green for a legitimate reason. Redone against both.Writing the registry also found a bug in the extracted parser: a CSS comment above a rule lands inside the selector capture, so the exact match never fires and a guarded rule reports as missing. That would have produced a false failure the moment someone documented the rule a contract guards. Comments are stripped first.
Dead code
Removes the
DocsSidebarwrapper and its.docs-sidebarrule — dead since #892 moved the docs nav into the control plane. OnlyDocsNavigationis imported, and the sole.docs-sidebarclass usage was inside the dead component. Its comment documented the samealign-selfhazard now held by the.docs-control-planecontract, so the knowledge is kept rather than deleted.Testing
432 tests pass, 0 lint errors, production build green.
🤖 Generated with Claude Code