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-2477Done

Sweep `--el-text-muted` off TINTED surfaces — it clears AA on the white card by 0.04 and fails everywhere else — and turn on the guard's muted arm

Carved out of MOTIR-2459 on 2026-08-08, the second of the two sweeps that card bundled. MOTIR-2455 measured this and called it "the subtler finding, and it catches more code"; it does, and it is a different kind of defect from the faint one, which is why it is a different card.

Repo: motir-core. One PR. Runs after MOTIR-2475 — both edit tests/theme/inkContrastLint.test.ts, and sequencing them keeps that file from being written twice.

The rule, and why this one is about PAIRS rather than about an ink

--el-text-muted is 4.54:1 on the white page/card — safe, by 0.04 — and 4.12–4.34:1 on --el-surface, --el-muted and --el-surface-soft, all of which fail. So unlike --el-text-faint, no site is a defect on its own: the verdict is a property of the ink AND the background under it. That is what makes this the harder sweep and the one with a real blind spot.

What the scanner measured, on origin/main at 0d5279da

130 violations across 75 files — muted TEXT (glyphs and disabled controls already filtered out, since 1.4.3 measures neither) whose nearest background-painting ancestor in the same file is one of the three tinted surfaces. Popovers, menus, sprint headers, soft-tinted cards and the auth shell are where they cluster.

⚠️ This number is a FLOOR, and the card must say so in its PR body rather than report a clean sweep. The scanner resolves an element's surface by walking up the JSX tree within one file. An element whose background is painted by a <Card>, a <Popover.Content> or a layout in ANOTHER module reads as "no surface found here" and the muted rule abstains. So the sites this card fixes are the ones a single file can prove; cross-component surface inheritance is out of the scanner's reach by construction and stays out of it.

The fix

Same substitution as the faint sweep: --el-text-secondary, which clears AA on all four surfaces in both themes, so it is correct without needing to know which surface the element ended up on. The alternative — moving each element onto --el-card — changes layout intent and is not this card's business.

Acceptance criteria

  • scanSource (from MOTIR-2459) reports zero muted violations across the scanned tree, asserted as a derivation over the scanned file set rather than against a frozen count of 130.
  • tests/theme/inkContrastLint.test.ts — the guard MOTIR-2475 lands — gains its muted arm, failing the build on muted ink over bg-(--el-surface), bg-(--el-surface-soft) or bg-(--el-muted), with the faint arm untouched and still green.
  • No allowlist, no exclusion. Every violation is fixed by moving the ink.
  • The guard's blind spot is stated in the test file itself: surface resolution stops at the file boundary, so a background painted by another module is not seen. A comment, not a silent limit — the card that widens it later needs to know where the edge is.
  • The PR body says explicitly which surfaces the guard could NOT rule on (cross-component backgrounds) instead of reporting a clean sweep, and names the a11y-sweep routes that do not cover the files touched.
  • pnpm lint, pnpm typecheck, pnpm prettier and next build pass; component tests asserting on a re-inked class are updated in the same PR.

Context refs

  • tests/theme/inkContrastScan.ts — the scanner and its nearestSurface walk (MOTIR-2459).
  • tests/theme/inkContrastLint.test.ts — the guard to extend (MOTIR-2475).
  • packages/design-system/theme.css — the two tokens and their comments.
  • motir-core/CLAUDE.md § The token map — the measured table.