Public: anyone can read this; the crew can change it.

The design lint refuses raw colours, z-index outside the tokens, and fixed boxes outside the overlay host #12019

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

The design lint now refuses a raw `z-index`, off-scale spacing, `position: fixed` and a full-viewport box outside `src/web/overlay_host.ts`. Today's violations are named as debt, not fixed. `bun scripts/design-lint.ts` passes on this tree, `bun x tsc --noEmit` is clean, and `test/design-lint.test.ts` passes (48 tests). I did not run the rest of the suite; the forge's check runs it on the push. I d…

shipped production is serving it deploy 1a20738

opened this

The design lint now refuses a raw z-index, off-scale spacing, position: fixed and a full-viewport box outside src/web/overlay_host.ts. Today's violations are named as debt, not fixed. bun scripts/design-lint.ts passes on this tree, bun x tsc --noEmit is clean, and test/design-lint.test.ts passes (48 tests). I did not run the rest of the suite; the forge's check runs it on the push. I did not call keep_plan or estimate.

What changed

  • Rules: the new module src/design/layout.ts reads every /* css */ template in src/web and checks four rules: zindex, fixed, viewport and space.

- zindex flags anything that is not var(--z-…), 0 or auto. - viewport flags a width or height of 100vw, 100vh or 100dvh. A viewport size used as a bound inside calc(), min() or max() is allowed. - space flags a px value in padding, margin or gap that is off the scale 2 4 6 8 12 16 24 32 48 64.

  • Refusals: each is one line: file:line rule: declaration → fix.
  • Debt: it is listed per file and rule under a new layout key in docs/design/baseline.json. It is 198 findings today. A pull can lower a file's count but not raise it, and --update rewrites it.
  • Wiring: scripts/design-lint.ts runs the rules and re-exports them. docs/design/sections/4-space-radius-motion.md has a "Layout is tokens" bullet.
  • Tests: test/design-lint.test.ts feeds the lint a sample for each violation and checks each is refused. It also checks the one-line message format, that the overlay host is exempt, that a bound is allowed, and that the real tree is no worse than its debt.

What I chose not to do

  • Colour: I added no new colour rule, because the existing colour ratchet already refuses raw colours and its baseline is empty.
  • Z tokens: the --z-* tokens do not exist yet, so the rule only accepts the name. The existing raw z-index values stay as named debt until a pull defines the tokens and moves them.
  • Fixed boxes: I did not move the existing fixed boxes in components.ts and space_client.ts into the overlay host.
  • Spacing: I did not rewrite the existing off-scale spacing.

To try it: run bun scripts/design-lint.ts, then add z-index: 99 to any /* css */ template to see the one-line refusal.

Closes #12017

commented

The design lint now refuses a raw z-index, off-scale spacing, position: fixed and a full-viewport box outside src/web/overlay_host.ts. Today's violations are named as debt, not fixed. bun scripts/design-lint.ts passes on this tree, bun x tsc --noEmit is clean, and test/design-lint.test.ts passes (48 tests). I did not run the rest of the suite; the forge's check runs it on the push. I did not call keep_plan or estimate.

What changed

  • Rules: the new module src/design/layout.ts reads every /* css */ template in src/web and checks four rules: zindex, fixed, viewport and space.

- zindex flags anything that is not var(--z-…), 0 or auto. - viewport flags a width or height of 100vw, 100vh or 100dvh. A viewport size used as a bound inside calc(), min() or max() is allowed. - space flags a px value in padding, margin or gap that is off the scale 2 4 6 8 12 16 24 32 48 64.

  • Refusals: each is one line: file:line rule: declaration → fix.
  • Debt: it is listed per file and rule under a new layout key in docs/design/baseline.json. It is 198 findings today. A pull can lower a file's count but not raise it, and --update rewrites it.
  • Wiring: scripts/design-lint.ts runs the rules and re-exports them. docs/design/sections/4-space-radius-motion.md has a "Layout is tokens" bullet.
  • Tests: test/design-lint.test.ts feeds the lint a sample for each violation and checks each is refused. It also checks the one-line message format, that the overlay host is exempt, that a bound is allowed, and that the real tree is no worse than its debt.

What I chose not to do

  • Colour: I added no new colour rule, because the existing colour ratchet already refuses raw colours and its baseline is empty.
  • Z tokens: the --z-* tokens do not exist yet, so the rule only accepts the name. The existing raw z-index values stay as named debt until a pull defines the tokens and moves them.
  • Fixed boxes: I did not move the existing fixed boxes in components.ts and space_client.ts into the overlay host.
  • Spacing: I did not rewrite the existing off-scale spacing.

To try it: run bun scripts/design-lint.ts, then add z-index: 99 to any /* css */ template to see the one-line refusal.

commented

The preview deploy did not fail, so I changed nothing and pushed nothing. The log ends done: … and the run's own summary is running at …, with the note "no tests declared, none run". The preview answers /healthz with 200.

That note comes from forge.json having no app.test, and it was already so on main. The forge's check runs the tests on each push, and test/design-lint.test.ts passes in that check, 48 tests.

If you want previews to run tests too, "test": "bun test test/design-lint.test.ts" under app would do it. It would also apply to production deploys and every other pull, so I left it for you to decide.

commented

The gate failure is fixed, and I pushed the fix. I didn't run any tests locally. scripts/fast.ts couldn't name tests (it reported the diff as too broad), so I left that to the forge's check on this push.

What changed: I rewrapped the comment block at the top of src/design/layout.ts so no line goes past 100 columns. The two long lines were the fixed and space entries in the rules list. I also dropped the long dashes in that list in favour of colons and shortened one phrase in the viewport entry. Only comments changed, not behaviour.

Checks run: bun scripts/gate.ts and bun x tsc --noEmit both pass. The gate only passed once the rewrap was committed, because it checks the lines the pull adds, not the working tree.

What to look at: the diff is just that comment block in src/design/layout.ts.

The pull itself is unchanged: the design lint refuses raw z-index, off-scale spacing, and fixed or full-viewport boxes outside the overlay host. Today's debt is named in docs/design/baseline.json.

Approved

The lint works: bun scripts/design-lint.ts passes on this tree and the design-lint tests pass. Each refusal is one line with the rule and the fix. Debt is named per file under layout in baseline.json, so it only shrinks. This is tooling, so there is no page or terminal surface to try, and the docs bullet sits in the design section, not README. Next two things: (1) define the --z-* tokens and move the 198 named debt entries toward zero, starting with the 7 z-index and 3 fixed entries in components.ts. The z-index rule currently accepts token names that do not exist, so also check that a --z-x name is defined. (2) Add a test for the raw-colour case in the new sample, or say in the test where the existing colour ratchet covers it. The space rule ignores var() fallbacks, which is fine but undocumented.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs