Skip to content

refactor(ui): normalize the renderer CSS cascade into explicit layers - #1654

Merged
Astro-Han merged 2 commits into
mainfrom
refactor/1565-pr1-cascade-normalization
Jul 30, 2026
Merged

refactor(ui): normalize the renderer CSS cascade into explicit layers#1654
Astro-Han merged 2 commits into
mainfrom
refactor/1565-pr1-cascade-normalization

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

PR 1 of the Astryx renderer migration (#1565, "PR 1 — Cascade normalization"): rewrite the renderer's implicit CSS cascade into an explicit, order-equivalent layered cascade. Refs #1565.

  • New cascade-layers.css is the single owner of the layer order (theme, base, components, utilities, maka.legacy) and becomes styles.css's first import, so the order is established before any CSS loads.
  • All Maka-owned unlayered product imports move into layer(maka.legacy), declared after utilities — they keep beating Tailwind utilities exactly as unlayered CSS did, and their intra-layer order is the unchanged import order.
  • The three imports already in layer(components) (chat-message.css, prose.css, markdown-link.css) are untouched.

Two files deviate from the issue's nominal "wrap everything Maka-owned / leave third-party unlayered" rule; both deviations were caught by the zero-diff gate, which is exactly the arbiter role #1565 assigns it:

  • maka-tokens.css stays unlayered: it declares its own @layer base / @layer utilities / @layer components blocks that must keep merging into the top-level Tailwind layers. Wrapping the import nests them under maka.legacy and lifts them above the utilities layer (observed as button borderColor / segmented-control flips in chat and settings).
  • overlayscrollbars joins maka.legacy: the library and the product CSS trade wins by specificity in both directions (e.g. the library's [data-overlayscrollbars-viewport]:not(...) reset vs .maka-chatViewport height rules), so no unlayered/layered split can preserve today's outcomes. Sharing the layer preserves the intra-layer specificity and source-order contests exactly (observed as a 40px onboarding viewport height shift before the fix).

Verification

  • check:visual-contract (PR 0's computed-style snapshot harness + baselines, borrowed locally from the PR 0 worktree): 10/10 captures clean, exact zero diff — all five routes (chat, settings-general, settings-providers, mcp-hub, onboarding) × light/dark.
  • Control run with main's styles.css against the same baselines confirmed the baselines represent current main on this machine.
  • check:hit-test: reports the same unhittable-element list on this branch and on an unmodified main build (identical elements, e.g. composer controls intercepted by .maka-overlay-scrollarea-viewport) — pre-existing behavior of the WIP harness/main, not a regression from this PR; owned by the PR 0 work.
  • npm run format:check, npm run typecheck, npm run check:release (includes the dead-CSS gate): all pass.
  • Desktop unit suite: 2979/2979 pass. Two pre-existing contract assertions (overlayscrollbars, segmented) hardcoded the unlayered import form and were adapted to the layered one.

Review follow-up

An independent review pass (subagent + Codex, both verifying the built CSS AST against main) confirmed order-equivalence and surfaced one actionable gap: the existing renderer-style-layer-cascade-contract.test.ts asserted the pre-#1565 model and stayed green through the rewrite because its helper drops import-site layer() semantics. The second commit re-anchors that contract on the new invariants — layer order is append-only with maka.legacy after utilities, every import sits in its contracted layer, and the .maka-nav-row files are pinned to maka.legacy — each mutation-checked (reordering the layers or demoting sidebar.css to layer(components) fails the suite). The CSS governance docs (EN + zh-CN) and the comments whose unlayered rationale the rewrite obsoleted are aligned in the same commit.

Merge order

Development was parallel to PR 0 (file-disjoint), but merge is serial: do not merge until PR 0 (visual-contract harness + baselines) is on main, then rebase and re-run check:visual-contract as the final gate. The harness scripts and baseline fixtures are deliberately not part of this PR — they ship with PR 0.

@Astro-Han
Astro-Han marked this pull request as draft July 30, 2026 10:20
Declare the layer order once in cascade-layers.css and move the Maka-owned
unlayered product imports into layer(maka.legacy), declared after utilities
so precedence is unchanged. Two files need special handling to stay
order-equivalent, both caught by the zero computed-style-diff gate:

- maka-tokens.css stays unlayered: it declares its own @layer base/
  utilities/components blocks that must keep merging into the top-level
  Tailwind layers instead of nesting under maka.legacy.
- overlayscrollbars joins maka.legacy: the library and the product CSS
  trade wins by specificity in both directions, so they must share a
  layer to preserve those contests.

The three imports already in layer(components) and the remaining
third-party imports keep their current standing.

Refs #1565
Review follow-up on the #1565 PR 1 cascade normalization. The existing
layer-cascade contract asserted the pre-#1565 model (rules win by being
unlayered) and stayed green through the rewrite because its helper drops
import-site layer() semantics. Re-anchor it on the new invariants:

- cascade-layers.css declares the five layers in order with maka.legacy
  after utilities, and styles.css loads it first (mutation-checked: a
  reorder fails the suite).
- every styles.css import sits in its contracted layer, with the
  deliberate unlayered exceptions enumerated; overlayscrollbars is
  pinned to maka.legacy.
- the .maka-nav-row guards now assert their files are imported into
  maka.legacy (mutation-checked: demoting sidebar.css to
  layer(components) fails the suite).

Adapt the overlayscrollbars and segmented import assertions to the
layered form, align the CSS governance docs, and update the comments
whose unlayered rationale the rewrite obsoleted.

Refs #1565
@Astro-Han
Astro-Han force-pushed the refactor/1565-pr1-cascade-normalization branch from 452b278 to 111bf21 Compare July 30, 2026 13:10
@Astro-Han
Astro-Han marked this pull request as ready for review July 30, 2026 13:11
@Astro-Han
Astro-Han merged commit de92fcf into main Jul 30, 2026
3 checks passed
@Astro-Han
Astro-Han deleted the refactor/1565-pr1-cascade-normalization branch July 30, 2026 13:11
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