Project unmatched author p-selectors through source-tag marker; keep button rows out of navigation (#630)#686
Merged
Conversation
An author rule whose selector matched no source element (e.g. `.page-header p` in a fixture whose `.page-header` has no source `<p>`) was emitted verbatim. Once a sibling `<div>` — such as an eyebrow `<div class="label">` — collapses to a paragraph, that dormant `.page-header p` rule suddenly captures it and overrides its own class-owned type scale, inflating the element and shifting the page. BE already projects descendant `p`/`li`/`nav` type selectors through a source-tag marker carried only by elements that were that tag in the source, so a promoted paragraph is never captured. That rewrite was skipped on the no-match branch, leaving the selector bare. Route the no-match case through the same rewriteSourceTagTypes() path, so `.page-header p` becomes `.page-header :where( .blocks-engine-source-p-...)` and matches only real source paragraphs. This replaces the earlier parallel collapsed-paragraph exclusion mechanism, which duplicated the source-tag-marker system and regressed the already-solved 15-saas fixture by adding markers and shifting the marker counter. The 15-saas transform is now byte-identical to trunk, while the 3-artist-music eyebrow keeps its 0.68rem scale. Full php-transformer suite green: 248 parity fixtures, 77 block-style-support tests, projection unit coverage, all contracts. Refs #630.
A row of button-styled links whose container carries an incidental navigational token (e.g. `<div class="stream-links"><a class="stream-btn">…</a>…</div>`, matched only because `links` looks navigational) was flattened into a core/navigation menu. That halved the controls' height (39.7px pill buttons became 20.5px text links) and dropped their styling, shifting the section. NavigationPattern now defers when a non-`nav`, non-list container's direct link children all carry button signals (via ButtonSignalClassifier). Those anchors belong to the buttons pattern, which converts the row to core/buttons and preserves each control's pill geometry and class. Genuine nav menus, list navigation, and single incidental button-classed links are unaffected. On the 3-artist-music music route this restores the streaming-links row to source parity. Full navigation + button unit suites and 248 parity fixtures green. Refs #630.
chubes4
force-pushed
the
fix/630-cross-route-collapse-cascade-isolation
branch
from
July 23, 2026 21:17
d9da87a to
46d28eb
Compare
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.
Summary
Two focused fidelity fixes for imported sites, both using existing BE mechanisms.
1. Project unmatched author type selectors through their source-tag marker
An author rule whose selector matched no source element — e.g.
.page-header pin a fixture whose.page-headercontains no source<p>(the intro paragraph lives elsewhere) — was emitted verbatim. Once a sibling<div>such as an eyebrow<div class="label">collapses to a paragraph, that dormant.page-header prule suddenly captures it at higher specificity and overrides its own class-owned type scale, inflating the element and shifting the whole page down.BE already projects descendant
p/li/navtype selectors through a source-tag marker carried only by elements that were that tag in the source (this is how.benefit-card pcorrectly avoids capturing a promoted.benefit-numeyebrow in the solved15-saasfixture). That rewrite was simply skipped on the no-match branch, leaving the selector bare. This routes the no-match case through the samerewriteSourceTagTypes()path, so.page-header pbecomes.page-header :where(.blocks-engine-source-p-…)and matches only real source paragraphs.2. Keep button-styled link rows out of core/navigation
A row of button-styled links whose container carries an incidental navigational token (e.g.
<div class="stream-links"><a class="stream-btn">…</a>…</div>, matched only becauselinkslooks navigational) was flattened into acore/navigationmenu — halving the controls' height (39.7px pills → 20.5px text links).NavigationPatternnow defers when a non-nav, non-list container's direct link children all carry button signals, so the row converts tocore/buttonsand keeps its pill geometry. Genuine nav menus, list navigation, and single incidental button-classed links are unaffected.Verification
15-saas(solved fixture) transform is byte-identical to trunk — no regression.3-artist-music: eyebrow keeps its type scale; streaming-links row restored to source parity.php-transformersuite green: 248 parity fixtures, 77 block-style-support tests, navigation + button unit suites, projection unit coverage, all contracts.AI assistance disclosure
Drafted with Claude (Sonnet 4.5) via opencode, used to trace the cascade through in-sandbox CSS/DOM inspection, root-cause a self-introduced regression against the solved-fixture gate, and re-implement through the existing source-tag-marker mechanism. Every line reviewed by Chris Huber.
Refs #630.