Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-2497Done

The ink scanner walks PAST an element's own white fill — `--el-page-bg` and `--el-card` are the same colour and only one of them stops the surface walk

Found while running MOTIR-2496 — one of the five sites that card cleared was a FALSE POSITIVE, and the ink moved there for reasons of its own. The misattribution is the class, and it is still in the scanner.

Repo: motir-core. One PR.

The measurement

nearestSurface in tests/theme/inkContrastScan.ts walks ancestors looking for the background an ink pairs with. It has exactly one early return for a SAFE surface:

if (/\bbg-\(--el-card\)/.test(blob)) return { className: blob, tinted: false };
const tinted = TINTED_SURFACE_CLASSES.find((surface) => blob.includes(surface));
if (tinted) return { className: tinted, tinted: true };

--el-page-bg is not in that check, and it is not in TINTED_SURFACE_CLASSES either — so the walk sails straight through an element that paints its own white background and keeps climbing until it finds a tinted ancestor.

Both tokens resolve to the same value:

--el-page-bg: var(--color-background);
--el-card:    var(--color-background);   /* untinted card surface */

So two elements painted identical white get opposite verdicts depending on which token the author reached for.

The instance

app/(authed)/backlog/_components/CreateIssueRow.tsx — the inline create-issue input carries bg-(--el-page-bg) on ITSELF, inside a row whose ancestor is --el-surface-soft. Its placeholder therefore paints on white (muted = 4.54:1, passing), and the guard reported it as 4.12–4.34:1 on bg-(--el-surface-soft).

MOTIR-2496 moved that placeholder to --el-text-secondary anyway — 4.54:1 is 0.04 of headroom on placeholder text, and its three sibling composers were moving in the same change — so the lane is green. The scanner is still wrong, and the next bg-(--el-page-bg) element inside a tinted container gets the same false verdict with no record of why.

Why it matters more than one false positive

A false POSITIVE in this guard is not free, and MOTIR-2489's own card said so: "it pushes the next author toward restructuring code to satisfy a parser rather than a reader." Here the cheapest way to silence it is to swap bg-(--el-page-bg) for bg-(--el-card) — zero pixels changed, guard satisfied, and the codebase now carries a token choice made for a parser. That is the outcome to prevent.

Acceptance criteria

  • nearestSurface treats an element's own bg-(--el-page-bg) as a TERMINATING SAFE surface, exactly as bg-(--el-card) already is — proven by a fixture in tests/theme/inkContrastScan.test.ts holding both arms: a muted ink on an element carrying bg-(--el-page-bg) INSIDE a bg-(--el-surface-soft) ancestor expects NO violation, and the same ink with no own-background expects one.
  • The safe-surface set is derived from, or asserted against, the fact that both tokens map to --color-background — a new white alias must not be able to reopen this silently. A test that reads theme.css and fails when a --el-* background maps to --color-background without appearing in the safe set is the shape to aim for.
  • tests/theme/inkContrastLint.test.ts still passes over the whole scanned tree, and the PR states the verdict census before and after so any site the correction newly SILENCES is visible — a fix that quietly drops real findings is the failure mode here.
  • No site is exempted or allowlisted to make this pass; the change is to the resolver.
  • pnpm lint, pnpm typecheck, pnpm prettier and next build pass.

Context refs

  • tests/theme/inkContrastScan.tsnearestSurface and TINTED_SURFACE_CLASSES.
  • tests/theme/inkContrastScan.test.ts — the fixture suite to extend.
  • packages/design-system/theme.css — the --el-page-bg / --el-card definitions, lines ~2240 and ~2455.
  • app/(authed)/backlog/_components/CreateIssueRow.tsx — the instance, and the comment MOTIR-2496 left on it naming this card.
  • MOTIR-2489 — the prior wrong-element card; same family, different function.