Skip to content

[diffs/edit] fix marker popover text contrast - #1061

Closed
necolas wants to merge 1 commit into
mainfrom
fix-diff-tooltip-contrast
Closed

[diffs/edit] fix marker popover text contrast#1061
necolas wants to merge 1 commit into
mainfrom
fix-diff-tooltip-contrast

Conversation

@necolas

@necolas necolas commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Description

contrast-color() takes one argument. The marker popover in editor.css passed two:

color: contrast-color(var(--diffs-marker-bg), var(--diffs-bg));

The arguments contain var(), so the browser cannot check the grammar at parse time and accepts the declaration. After substitution the value is invalid, so the declaration becomes invalid at computed-value time. color is an inherited property, so it then resolves to the inherited value. It does not fall back to the earlier color: var(--diffs-marker-contrast) declaration, because the cascade already chose a winner.

The popover therefore showed the near-white editor foreground on the severity fill.

The fix passes one argument. contrast-color() still adapts to a theme-supplied fill (editorWarning.foreground and the similar tokens), which the hard-coded per-severity fallback cannot do.

Motivation & Context

A user reported poor contrast on the editor lint tooltip in the diffs docs app. The defect is in @pierre/diffs, not in the docs app. The docs app uses workspace:*, so it picks the fix up on the next build. Published consumers on 1.3.4 need a version bump.

Measured in Chrome 151 against the real stylesheet, with the existing e2e contrast test:

State Text on fill Ratio
Before rgb(250, 250, 250) on rgb(0, 159, 255) 2.72:1 — fails AA
After black or white per fill 5.71:1 or better

All four severities in both themes now clear WCAG AA. contrast-color() picks white for the light-theme hint (dark grey fill) and black elsewhere.

CI could not catch this. Playwright 1.51.1 bundles Chromium 134, which predates contrast-color(), so the existing contrast test only ever measured the @supports fallback branch — the branch that was already correct.

cssContrastColorArity.test.ts closes that gap. It parses the shipped CSS with balanced-paren scanning and asserts one top-level argument per contrast-color() call. It runs in Bun with no browser, so it holds whatever browser CI uses. Confirmed red/green: it fails on the original CSS with contrast-color(var(--diffs-marker-bg), var(--diffs-bg)) must take exactly one argument.

Type of changes

  • Bug fix (non-breaking change which fixes an issue)
  • Refactoring (non-breaking change)
  • New feature (non-breaking change which adds functionality). You must have
    first discussed with the dev team and they should be aware that this PR is
    being opened
  • Breaking change (fix or feature that would change existing functionality).
    You must have first discussed with the dev team and they should be aware
    that this PR is being opened
  • Documentation update

Checklist

  • I have read the
    contributing guidelines
  • My code follows the code style of the project (moon run root:lint)
  • My code is formatted properly (moon run root:format)
  • I have updated the documentation accordingly (if applicable)
  • I have added tests to cover my changes (if applicable)
  • All new and existing tests pass (moonx diffs:test — 1504 pass, 0 fail)

Also ran moonx diffs:typecheck (clean) and markers.pw.ts in system Chrome 151 (5 passed).

How was AI used in generating this PR

Claude Code (Opus 5) did the whole change: it traced the root cause, wrote the CSS fix and the regression test, and drafted this description. It verified the diagnosis in a real browser rather than by reasoning alone — it built a standalone harness in Chrome 151 to confirm that CSS.supports('color', 'contrast-color(red, blue)') is false while the one-argument form is true, then reproduced and fixed the failure end to end through the package's own e2e fixture.

Related issues

None. Reported by a user against the diffs docs app.

Notes for the reviewer

Two open points I did not act on:

  1. Release. This needs a @pierre/diffs version bump for published consumers. Your history keeps those as separate chore: bump commits, so I left it out.
  2. Hint severity in e2e. The contrast test covers info, error, and warning. The fixture's hint marker sits at character 80–100, off screen, and the scrolled-gutter test uses it, so a hover needs the horizontal-scroll setup. Hint was already uncovered before this change, and I measured it as 8.23:1 dark and 7.81:1 light, so I left the e2e coverage as it was.

`contrast-color()` takes one argument. The marker popover passed two,
which makes the declaration invalid at computed-value time. `color` then
inherited the editor foreground, so the popover showed near-white text
on the yellow warning fill.

Chrome 151 measured 2.72:1 before the fix and 5.71:1 or better after it,
across every severity and both themes.

Playwright bundles an old Chromium without `contrast-color()`, so the
existing e2e contrast test runs the fallback branch only. Add a static
test that checks the argument count in the shipped CSS.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pierre-docs-diffs Ready Ready Preview Aug 6, 2026 5:07am
pierre-docs-diffshub Ready Ready Preview Aug 6, 2026 5:07am
pierre-docs-trees Ready Ready Preview Aug 6, 2026 5:07am
pierrejs-diff-demo Ready Ready Preview Aug 6, 2026 5:07am

Request Review

ignores the `--diffs-marker-contrast` declaration above. */
@supports (color: contrast-color(red)) {
color: contrast-color(var(--diffs-marker-bg), var(--diffs-bg));
color: contrast-color(var(--diffs-marker-bg));

@mdo mdo Aug 6, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To keep the intent here, this was meant to be a fallback. Can probably update the code comment to remove mention of two colors.

Suggested change
color: contrast-color(var(--diffs-marker-bg));
color: contrast-color(var(--diffs-marker-bg, var(--diffs-bg)));

@necolas

necolas commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Closing in favor of #1062

@necolas necolas closed this Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants