04 TRACEWhat is left behind?

The layer order had quietly inverted

No error, no warning — a handful of declarations stopped applying. CSS layer order comes from first appearance, not from the source list.

The hero's spacing was wrong. A margin was set and it sat flush.

getComputedStyle(h1).marginBottom  // "0px"

The class was attached, and no matching rule existed.

Cause

Put plainly: layers are an order to stand in, and whoever stands later wins. But the thing deciding that order was not the list I wrote — it was arrival order.

The list I wrote (layers.css)resettokensbasecomponents← should winThe order the bundler actually emittedcomponentsresettokensbasecomponents got pushed to the front, so reset — standing later —won, and its global margin-zero rule beat the component styles.

CSS layer order is set by first appearance, not by the @layer a, b, c; statement. If the bundler emits an @layer components { … } block before styles/layers.css, the declared order is discarded and rebuilt from appearance order.

The result was that components landed below reset. * { margin: 0 } was beating the component styles.

The Phase 0 page was in the same state. I looked at a screenshot and approved it while the spacing was already dead.

What changed

CSS Modules came out of the layers entirely. They are already scoped, and an unlayered rule takes precedence over every layered one. Whatever order the bundler emits stops mattering.

And pnpm check:layers was added. It reads the actual built CSS to confirm that the first @layer token is the order statement, that the order matches the source, and that no module has re-entered a layer.

A failure that is silent stays silent forever without a guard.

cssdebugging

Record

First committed 2026.08.24, and changed 2 times since.

  • 9cf738eContent: 어려운 대목 넷을 그림으로 바꿨다
  • 029cadaTopics: a controlled axis to browse by, and a filter that costs no JavaScript
  • 8987da1Phase 2: Personal System

The full build record →