system.cssthe engine GitHub

The cascade constitution

THE CASCADE CONSTITUTION (hard laws)

  1. Layers decide the cascade. Within a layer, specificity is ZERO. Every selector is wrapped in :where(...), and :not() guards go INSIDE the :where(). No ID selectors, no !important outside the media and skin layers (config switches that must out-cascade), no specificity battles. A specificity conflict is a SYSTEM FAILURE requiring root-cause review — never patch it with a more-specific selector.
  2. Do not touch engine internals when the public API suffices. Internal vars are --_-prefixed (--_bg, --_sem-ink). Author with the public knobs above. If you find yourself reaching for --_sem-ink, stop — you almost certainly want --hue-lock + --fg instead.
  3. The right LAYER owns the change. Region surfaces (pg-* --bg) ship in the skin layer; an app recipe that has settled graduates into the engine's own components layer (the project layer RETIRED 2026-09-01, gf-133 — ProjectStyles is gone); a public page's one-off look lives in that page's own @scope block (the landing's idiom). A rule in the wrong layer is silently out-cascaded — that is a layer-placement bug, never a specificity problem to fight.
  4. NO NEW CSS CLASSES (gf-185, per Mike, at maximum emphasis). The engine's whole point is explicit declarative HTML composed from the EXISTING composition classes + the style API (--type/--bg/--fg/ --hue-shift/--hue-lock/--lift/--gap) — never a new class per feature. A vertical stepper, a card variant, a layout arrangement: composition (.row/.column + knobs + the ARIA-state idioms + native elements like ), not a class. The EXCEPTION LIST is components that require CLIENT STATE (the google-maps rocket, the date picker) plus Mike's named three — .wash, the landing's @scope, .app-icon — nothing else qualifies without an explicit conversation with Mike. When composition genuinely cannot express something, that is a gap to RAISE (evolve a composition class, or extend the exception list — at the lab bench, with Mike), never a silent new class. Class sprawl "enables a corruption that is mathematically impossible to overcome after a certain point." Corollary: every NEW component or convention is demoed in THE LAB (system-css/site/lab, published at https://deufel.github.io/system-css/lab/) and aligned with Mike BEFORE product use.

Enforcement is Go now (the cowork-era conformance.py is long gone): go test ./... runs view/ratchet_test.go — the INLINE-GEOMETRY ratchet (style= is sanctioned only for --knobs, anchor-name/position-anchor, and commented one-offs; per-.templ counts may only go DOWN), the icon 24px-box ratchet, and the anatomy-reach ratchet (project CSS may not restyle engine anatomy). The cssaudit package charts lines-per-layer complexity on the admin Metrics page. Keep them all green.