Skip to content

Differentiate fgColor.done from upsell in dark protanopia & deuteranopia#1402

Merged
janmaarten-a11y merged 2 commits into
mainfrom
janmaarten-a11y/dark-pd-done-color-fix
Jun 12, 2026
Merged

Differentiate fgColor.done from upsell in dark protanopia & deuteranopia#1402
janmaarten-a11y merged 2 commits into
mainfrom
janmaarten-a11y/dark-pd-done-color-fix

Conversation

@janmaarten-a11y

Copy link
Copy Markdown
Contributor

Summary

In the dark-protanopia-deuteranopia theme, fgColor.done and fgColor.upsell both resolved to base.color.purple.4 (#AB7DF8), making "done" state indicators visually indistinguishable from "in progress" / upsell-styled indicators when adjacent. This was the regression reported in github/accessibility-external#926 and community discussion #149256.

Why a neutral, not another hue

Under deutan/protan simulation (Vienot 1999), purple.4 collapses toward the same hue as fgColor.success, fgColor.open, and fgColor.attention, so no remaining chromatic slot is perceptually safe for done. Pink collapses to gray and collides with closed. Blue collides with success/open. Yellow collides with attention. A neutral with a different lightness from closed/muted is the only collision-free option.

Changes

  • fgColor.donebase.color.neutral.10 (#B7BDC8) in dark-protanopia-deuteranopia
    • Brighter than fgColor.closed / fgColor.muted (neutral.9 / #9198A1) — distinguishable by lightness
    • Dimmer than default body text (neutral.12)
    • Passes WCAG AA (4.5:1) against all dark-pd backgrounds
  • fgColor.upsell pinned to base.color.purple.4 in dark-protanopia-deuteranopia
    • Previously inherited from fgColor.done; pinned so promotional content keeps its purple independent of the done change

Scope notes

  • Default dark theme is intentionally unchanged. This is a colorblind-theme-only fix per the original ticket scope.
  • Dark-pd HC variant is unchanged in this PR. Top of the neutral scale in HC is already used by closed (n10), draft (n11), and body text (n12), so a clean slot for done doesn't exist there without a broader rework. Flagging for a follow-up.

Verification

  • npm run lint && npm run format && npm run test && npm run build all pass
  • Built dist/css/functional/themes/dark-colorblind.css shows the expected diff:
    --fgColor-done: #b7bdc8;   /* was: #ab7df8 */
    --fgColor-upsell: #ab7df8; /* was: var(--fgColor-done) → #ab7df8, unchanged in resolved value */
    
  • HC variant dist/css/functional/themes/dark-colorblind-high-contrast.css is byte-identical: --fgColor-done: #d3abff still.

Background

See github/accessibility-external#926 for the full investigation, including: why no recent dependency bump caused the user's perceived regression, why the experimental primitives package isn't the culprit, and why a token-level fix here is the right layer.

…eranopia theme

In the dark-protanopia-deuteranopia theme, fgColor.done and fgColor.upsell
both resolved to base.color.purple.4 (#AB7DF8), making 'done' state
indicators visually indistinguishable from 'in progress' / upsell-styled
indicators when adjacent.

Under deutan/protan simulation, purple also collapses toward the same hue
as fgColor.open, fgColor.success, and fgColor.attention, so no chromatic
slot is perceptually safe. This change moves fgColor.done to a brighter
neutral (base.color.neutral.10 / #B7BDC8) that:

- Differentiates from fgColor.upsell (kept as purple via a new override)
- Differentiates from fgColor.closed / fgColor.muted (neutral.9) by
  lightness rather than hue
- Stays dimmer than default body text (neutral.12)
- Passes WCAG AA contrast against dark-pd backgrounds

The HC variant of this theme is unchanged in this PR; available neutral
scale slots in HC are already occupied (closed, draft, body text) and
need a separate scoping pass.

Closes user-reported regression in github/accessibility-external#926.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 11, 2026 22:04
@janmaarten-a11y janmaarten-a11y requested a review from a team as a code owner June 11, 2026 22:04
@changeset-bot

changeset-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9761d87

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@primer/primitives Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copilot AI left a comment

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.

Pull request overview

Updates the dark-protanopia-deuteranopia functional foreground tokens so completed (“done”) indicators are visually distinct from upsell/promotional purple in that specific colorblind theme.

Changes:

  • Override fgColor.done in dark-protanopia-deuteranopia to base.color.neutral.10 to avoid collisions with upsell/open/success/attention under deutan/protan simulation.
  • Pin fgColor.upsell in dark-protanopia-deuteranopia to base.color.purple.4 so upsell stays purple even though fgColor.done no longer is.
  • Add a Changesets entry to publish the token change.
Show a summary per file
File Description
src/tokens/functional/color/fgColor.json5 Adjusts theme-specific overrides so done becomes neutral while upsell remains purple in dark protanopia/deuteranopia.
.changeset/dark-pd-done-differentiation.md Records the release note/version bump for the token behavior change.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 2/2 changed files
  • Comments generated: 0

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Design Token Diff (CSS)

/css/functional/themes/dark-colorblind.css

+++ /home/runner/work/primitives/primitives/dist/css/functional/themes/dark-colorblind.css	2026-06-12 17:11:23.355096764 +0000
@@ -476,7 +476,7 @@
 --fgColor-danger: #f0883e; /** Danger text for errors and destructive actions */
 --fgColor-default: #f0f6fc; /** Default text color for primary content and headings */
 --fgColor-disabled: #656c76; /** Text color for disabled interactive elements */
-  --fgColor-done: #ab7df8; /** Text color for completed/done state indicators */
+  --fgColor-done: #b7bdc8; /** Text color for completed/done state indicators */
 --fgColor-link: var(--fgColor-accent); /** Text color for hyperlinks */
 --fgColor-muted: #9198a1; /** Muted text for secondary content and less important information */
 --fgColor-neutral: #9198a1; /** Neutral semantic text for icons and secondary elements */
@@ -484,6 +484,7 @@
 --fgColor-severe: #db6d28; /** Severe text for high-priority warnings */
 --fgColor-sponsors: #db61a2; /** Text color for GitHub Sponsors content */
 --fgColor-success: #58a6ff; /** Success text for positive feedback and completed states */
+  --fgColor-upsell: #ab7df8; /** Text color for upsell and promotional content */
 --header-bgColor: #151b23f2;
 --header-borderColor-divider: #656c76;
 --header-fgColor-logo: #f0f6fc;
@@ -844,7 +845,6 @@
 --fgColor-draft: var(--fgColor-neutral); /** Text color for draft state indicators */
 --fgColor-onEmphasis: #ffffff; /** Text color for use on emphasis backgrounds */
 --fgColor-onInverse: #010409; /** Text color for use on inverse backgrounds */
-  --fgColor-upsell: var(--fgColor-done); /** Text color for upsell and promotional content */
 --fgColor-white: #ffffff; /** Pure white text */
 --focus-outline-color: var(--borderColor-accent-emphasis); /** Outline color for focus states on interactive elements */
 --header-fgColor-default: #ffffffb3;
@@ -1438,7 +1438,7 @@
   --fgColor-danger: #f0883e; /** Danger text for errors and destructive actions */
   --fgColor-default: #f0f6fc; /** Default text color for primary content and headings */
   --fgColor-disabled: #656c76; /** Text color for disabled interactive elements */
-    --fgColor-done: #ab7df8; /** Text color for completed/done state indicators */
+    --fgColor-done: #b7bdc8; /** Text color for completed/done state indicators */
   --fgColor-link: var(--fgColor-accent); /** Text color for hyperlinks */
   --fgColor-muted: #9198a1; /** Muted text for secondary content and less important information */
   --fgColor-neutral: #9198a1; /** Neutral semantic text for icons and secondary elements */
@@ -1446,6 +1446,7 @@
   --fgColor-severe: #db6d28; /** Severe text for high-priority warnings */
   --fgColor-sponsors: #db61a2; /** Text color for GitHub Sponsors content */
   --fgColor-success: #58a6ff; /** Success text for positive feedback and completed states */
+    --fgColor-upsell: #ab7df8; /** Text color for upsell and promotional content */
   --header-bgColor: #151b23f2;
   --header-borderColor-divider: #656c76;
   --header-fgColor-logo: #f0f6fc;
@@ -1806,7 +1807,6 @@
   --fgColor-draft: var(--fgColor-neutral); /** Text color for draft state indicators */
   --fgColor-onEmphasis: #ffffff; /** Text color for use on emphasis backgrounds */
   --fgColor-onInverse: #010409; /** Text color for use on inverse backgrounds */
-    --fgColor-upsell: var(--fgColor-done); /** Text color for upsell and promotional content */
   --fgColor-white: #ffffff; /** Pure white text */
   --focus-outline-color: var(--borderColor-accent-emphasis); /** Outline color for focus states on interactive elements */
   --header-fgColor-default: #ffffffb3;

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Design Token Diff (StyleLint)

/styleLint/functional/themes/dark-colorblind-high-contrast.json

+++ /home/runner/work/primitives/primitives/dist/styleLint/functional/themes/dark-colorblind-high-contrast.json	2026-06-12 17:11:20.057990258 +0000
@@ -39295,6 +39295,7 @@
     },
     "org.primer.overrides": {
       "dark": "#bf8fff",
+        "dark-protanopia-deuteranopia": "#b7bdc8",
       "dark-high-contrast": "#D3ABFF",
       "dark-dimmed-high-contrast": "#e6ccff",
       "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39325,6 +39326,7 @@
       },
       "org.primer.overrides": {
         "dark": "{base.color.purple.4}",
+          "dark-protanopia-deuteranopia": "{base.color.neutral.10}",
         "dark-high-contrast": "#D3ABFF",
         "dark-dimmed-high-contrast": "{base.color.purple.1}",
         "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39934,6 +39936,9 @@
         "web": "var(--fgColor-upsell)"
       }
     },
+      "org.primer.overrides": {
+        "dark-protanopia-deuteranopia": "#bf8fff"
+      },
     "org.primer.llm": {
       "usage": ["upsell-text", "premium-text", "promotional"],
       "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."
@@ -39954,6 +39959,9 @@
           "web": "var(--fgColor-upsell)"
         }
       },
+        "org.primer.overrides": {
+          "dark-protanopia-deuteranopia": "{base.color.purple.4}"
+        },
       "org.primer.llm": {
         "usage": ["upsell-text", "premium-text", "promotional"],
         "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."

/styleLint/functional/themes/dark-colorblind.json

+++ /home/runner/work/primitives/primitives/dist/styleLint/functional/themes/dark-colorblind.json	2026-06-12 17:11:18.137928234 +0000
@@ -39273,7 +39273,7 @@
 },
 "fgColor-done": {
   "key": "{fgColor.done}",
-    "$value": "#ab7df8",
+    "$value": "#b7bdc8",
   "$type": "color",
   "$description": "Text color for completed/done state indicators",
   "$extensions": {
@@ -39287,6 +39287,7 @@
     },
     "org.primer.overrides": {
       "dark": "#ab7df8",
+        "dark-protanopia-deuteranopia": "#b7bdc8",
       "dark-high-contrast": "#D3ABFF",
       "dark-dimmed-high-contrast": "#e2c5ff",
       "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39303,7 +39304,7 @@
   "filePath": "src/tokens/functional/color/fgColor.json5",
   "isSource": true,
   "original": {
-      "$value": "{base.color.purple.4}",
+      "$value": "{base.color.neutral.10}",
     "$type": "color",
     "$description": "Text color for completed/done state indicators",
     "$extensions": {
@@ -39317,6 +39318,7 @@
       },
       "org.primer.overrides": {
         "dark": "{base.color.purple.4}",
+          "dark-protanopia-deuteranopia": "{base.color.neutral.10}",
         "dark-high-contrast": "#D3ABFF",
         "dark-dimmed-high-contrast": "{base.color.purple.1}",
         "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39926,6 +39928,9 @@
         "web": "var(--fgColor-upsell)"
       }
     },
+      "org.primer.overrides": {
+        "dark-protanopia-deuteranopia": "#ab7df8"
+      },
     "org.primer.llm": {
       "usage": ["upsell-text", "premium-text", "promotional"],
       "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."
@@ -39934,7 +39939,7 @@
   "filePath": "src/tokens/functional/color/fgColor.json5",
   "isSource": true,
   "original": {
-      "$value": "{fgColor.done}",
+      "$value": "{base.color.purple.4}",
     "$type": "color",
     "$description": "Text color for upsell and promotional content",
     "$extensions": {
@@ -39946,6 +39951,9 @@
           "web": "var(--fgColor-upsell)"
         }
       },
+        "org.primer.overrides": {
+          "dark-protanopia-deuteranopia": "{base.color.purple.4}"
+        },
       "org.primer.llm": {
         "usage": ["upsell-text", "premium-text", "promotional"],
         "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."

/styleLint/functional/themes/dark-dimmed-high-contrast.json

+++ /home/runner/work/primitives/primitives/dist/styleLint/functional/themes/dark-dimmed-high-contrast.json	2026-06-12 17:11:12.479746064 +0000
@@ -39305,6 +39305,7 @@
     },
     "org.primer.overrides": {
       "dark": "#986ee2",
+        "dark-protanopia-deuteranopia": "#b7bdc8",
       "dark-high-contrast": "#D3ABFF",
       "dark-dimmed-high-contrast": "#dcbdfb",
       "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39335,6 +39336,7 @@
       },
       "org.primer.overrides": {
         "dark": "{base.color.purple.4}",
+          "dark-protanopia-deuteranopia": "{base.color.neutral.10}",
         "dark-high-contrast": "#D3ABFF",
         "dark-dimmed-high-contrast": "{base.color.purple.1}",
         "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39944,6 +39946,9 @@
         "web": "var(--fgColor-upsell)"
       }
     },
+      "org.primer.overrides": {
+        "dark-protanopia-deuteranopia": "#986ee2"
+      },
     "org.primer.llm": {
       "usage": ["upsell-text", "premium-text", "promotional"],
       "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."
@@ -39964,6 +39969,9 @@
           "web": "var(--fgColor-upsell)"
         }
       },
+        "org.primer.overrides": {
+          "dark-protanopia-deuteranopia": "{base.color.purple.4}"
+        },
       "org.primer.llm": {
         "usage": ["upsell-text", "premium-text", "promotional"],
         "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."

/styleLint/functional/themes/dark-dimmed.json

+++ /home/runner/work/primitives/primitives/dist/styleLint/functional/themes/dark-dimmed.json	2026-06-12 17:11:10.532683523 +0000
@@ -39325,6 +39325,7 @@
     },
     "org.primer.overrides": {
       "dark": "#986ee2",
+        "dark-protanopia-deuteranopia": "#b7bdc8",
       "dark-high-contrast": "#D3ABFF",
       "dark-dimmed-high-contrast": "#dcbdfb",
       "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39355,6 +39356,7 @@
       },
       "org.primer.overrides": {
         "dark": "{base.color.purple.4}",
+          "dark-protanopia-deuteranopia": "{base.color.neutral.10}",
         "dark-high-contrast": "#D3ABFF",
         "dark-dimmed-high-contrast": "{base.color.purple.1}",
         "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39964,6 +39966,9 @@
         "web": "var(--fgColor-upsell)"
       }
     },
+      "org.primer.overrides": {
+        "dark-protanopia-deuteranopia": "#986ee2"
+      },
     "org.primer.llm": {
       "usage": ["upsell-text", "premium-text", "promotional"],
       "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."
@@ -39984,6 +39989,9 @@
           "web": "var(--fgColor-upsell)"
         }
       },
+        "org.primer.overrides": {
+          "dark-protanopia-deuteranopia": "{base.color.purple.4}"
+        },
       "org.primer.llm": {
         "usage": ["upsell-text", "premium-text", "promotional"],
         "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."

/styleLint/functional/themes/dark-high-contrast.json

+++ /home/runner/work/primitives/primitives/dist/styleLint/functional/themes/dark-high-contrast.json	2026-06-12 17:11:22.038054219 +0000
@@ -39295,6 +39295,7 @@
     },
     "org.primer.overrides": {
       "dark": "#bf8fff",
+        "dark-protanopia-deuteranopia": "#b7bdc8",
       "dark-high-contrast": "#D3ABFF",
       "dark-dimmed-high-contrast": "#e6ccff",
       "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39325,6 +39326,7 @@
       },
       "org.primer.overrides": {
         "dark": "{base.color.purple.4}",
+          "dark-protanopia-deuteranopia": "{base.color.neutral.10}",
         "dark-high-contrast": "#D3ABFF",
         "dark-dimmed-high-contrast": "{base.color.purple.1}",
         "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39934,6 +39936,9 @@
         "web": "var(--fgColor-upsell)"
       }
     },
+      "org.primer.overrides": {
+        "dark-protanopia-deuteranopia": "#bf8fff"
+      },
     "org.primer.llm": {
       "usage": ["upsell-text", "premium-text", "promotional"],
       "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."
@@ -39954,6 +39959,9 @@
           "web": "var(--fgColor-upsell)"
         }
       },
+        "org.primer.overrides": {
+          "dark-protanopia-deuteranopia": "{base.color.purple.4}"
+        },
       "org.primer.llm": {
         "usage": ["upsell-text", "premium-text", "promotional"],
         "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."

/styleLint/functional/themes/dark-tritanopia-high-contrast.json

+++ /home/runner/work/primitives/primitives/dist/styleLint/functional/themes/dark-tritanopia-high-contrast.json	2026-06-12 17:11:16.214866113 +0000
@@ -39303,6 +39303,7 @@
     },
     "org.primer.overrides": {
       "dark": "#bf8fff",
+        "dark-protanopia-deuteranopia": "#b7bdc8",
       "dark-high-contrast": "#D3ABFF",
       "dark-dimmed-high-contrast": "#e6ccff",
       "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39333,6 +39334,7 @@
       },
       "org.primer.overrides": {
         "dark": "{base.color.purple.4}",
+          "dark-protanopia-deuteranopia": "{base.color.neutral.10}",
         "dark-high-contrast": "#D3ABFF",
         "dark-dimmed-high-contrast": "{base.color.purple.1}",
         "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39942,6 +39944,9 @@
         "web": "var(--fgColor-upsell)"
       }
     },
+      "org.primer.overrides": {
+        "dark-protanopia-deuteranopia": "#bf8fff"
+      },
     "org.primer.llm": {
       "usage": ["upsell-text", "premium-text", "promotional"],
       "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."
@@ -39962,6 +39967,9 @@
           "web": "var(--fgColor-upsell)"
         }
       },
+        "org.primer.overrides": {
+          "dark-protanopia-deuteranopia": "{base.color.purple.4}"
+        },
       "org.primer.llm": {
         "usage": ["upsell-text", "premium-text", "promotional"],
         "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."

/styleLint/functional/themes/dark-tritanopia.json

+++ /home/runner/work/primitives/primitives/dist/styleLint/functional/themes/dark-tritanopia.json	2026-06-12 17:11:14.339805810 +0000
@@ -39309,6 +39309,7 @@
     },
     "org.primer.overrides": {
       "dark": "#ab7df8",
+        "dark-protanopia-deuteranopia": "#b7bdc8",
       "dark-high-contrast": "#D3ABFF",
       "dark-dimmed-high-contrast": "#e2c5ff",
       "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39339,6 +39340,7 @@
       },
       "org.primer.overrides": {
         "dark": "{base.color.purple.4}",
+          "dark-protanopia-deuteranopia": "{base.color.neutral.10}",
         "dark-high-contrast": "#D3ABFF",
         "dark-dimmed-high-contrast": "{base.color.purple.1}",
         "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39948,6 +39950,9 @@
         "web": "var(--fgColor-upsell)"
       }
     },
+      "org.primer.overrides": {
+        "dark-protanopia-deuteranopia": "#ab7df8"
+      },
     "org.primer.llm": {
       "usage": ["upsell-text", "premium-text", "promotional"],
       "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."
@@ -39968,6 +39973,9 @@
           "web": "var(--fgColor-upsell)"
         }
       },
+        "org.primer.overrides": {
+          "dark-protanopia-deuteranopia": "{base.color.purple.4}"
+        },
       "org.primer.llm": {
         "usage": ["upsell-text", "premium-text", "promotional"],
         "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."

/styleLint/functional/themes/dark.json

+++ /home/runner/work/primitives/primitives/dist/styleLint/functional/themes/dark.json	2026-06-12 17:11:08.564620307 +0000
@@ -39281,6 +39281,7 @@
     },
     "org.primer.overrides": {
       "dark": "#ab7df8",
+        "dark-protanopia-deuteranopia": "#b7bdc8",
       "dark-high-contrast": "#D3ABFF",
       "dark-dimmed-high-contrast": "#e2c5ff",
       "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39311,6 +39312,7 @@
       },
       "org.primer.overrides": {
         "dark": "{base.color.purple.4}",
+          "dark-protanopia-deuteranopia": "{base.color.neutral.10}",
         "dark-high-contrast": "#D3ABFF",
         "dark-dimmed-high-contrast": "{base.color.purple.1}",
         "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39920,6 +39922,9 @@
         "web": "var(--fgColor-upsell)"
       }
     },
+      "org.primer.overrides": {
+        "dark-protanopia-deuteranopia": "#ab7df8"
+      },
     "org.primer.llm": {
       "usage": ["upsell-text", "premium-text", "promotional"],
       "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."
@@ -39940,6 +39945,9 @@
           "web": "var(--fgColor-upsell)"
         }
       },
+        "org.primer.overrides": {
+          "dark-protanopia-deuteranopia": "{base.color.purple.4}"
+        },
       "org.primer.llm": {
         "usage": ["upsell-text", "premium-text", "promotional"],
         "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."

/styleLint/functional/themes/light-colorblind-high-contrast.json

+++ /home/runner/work/primitives/primitives/dist/styleLint/functional/themes/light-colorblind-high-contrast.json	2026-06-12 17:11:04.672495697 +0000
@@ -39281,6 +39281,7 @@
     },
     "org.primer.overrides": {
       "dark": "#844ae7",
+        "dark-protanopia-deuteranopia": "#454c54",
       "dark-high-contrast": "#D3ABFF",
       "dark-dimmed-high-contrast": "#e0c5ff",
       "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39311,6 +39312,7 @@
       },
       "org.primer.overrides": {
         "dark": "{base.color.purple.4}",
+          "dark-protanopia-deuteranopia": "{base.color.neutral.10}",
         "dark-high-contrast": "#D3ABFF",
         "dark-dimmed-high-contrast": "{base.color.purple.1}",
         "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39920,6 +39922,9 @@
         "web": "var(--fgColor-upsell)"
       }
     },
+      "org.primer.overrides": {
+        "dark-protanopia-deuteranopia": "#844ae7"
+      },
     "org.primer.llm": {
       "usage": ["upsell-text", "premium-text", "promotional"],
       "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."
@@ -39940,6 +39945,9 @@
           "web": "var(--fgColor-upsell)"
         }
       },
+        "org.primer.overrides": {
+          "dark-protanopia-deuteranopia": "{base.color.purple.4}"
+        },
       "org.primer.llm": {
         "usage": ["upsell-text", "premium-text", "promotional"],
         "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."

/styleLint/functional/themes/light-colorblind.json

+++ /home/runner/work/primitives/primitives/dist/styleLint/functional/themes/light-colorblind.json	2026-06-12 17:11:02.829436738 +0000
@@ -39271,6 +39271,7 @@
     },
     "org.primer.overrides": {
       "dark": "#a475f9",
+        "dark-protanopia-deuteranopia": "#454c54",
       "dark-high-contrast": "#D3ABFF",
       "dark-dimmed-high-contrast": "#ecd8ff",
       "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39301,6 +39302,7 @@
       },
       "org.primer.overrides": {
         "dark": "{base.color.purple.4}",
+          "dark-protanopia-deuteranopia": "{base.color.neutral.10}",
         "dark-high-contrast": "#D3ABFF",
         "dark-dimmed-high-contrast": "{base.color.purple.1}",
         "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39910,6 +39912,9 @@
         "web": "var(--fgColor-upsell)"
       }
     },
+      "org.primer.overrides": {
+        "dark-protanopia-deuteranopia": "#a475f9"
+      },
     "org.primer.llm": {
       "usage": ["upsell-text", "premium-text", "promotional"],
       "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."
@@ -39930,6 +39935,9 @@
           "web": "var(--fgColor-upsell)"
         }
       },
+        "org.primer.overrides": {
+          "dark-protanopia-deuteranopia": "{base.color.purple.4}"
+        },
       "org.primer.llm": {
         "usage": ["upsell-text", "premium-text", "promotional"],
         "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."

/styleLint/functional/themes/light-high-contrast.json

+++ /home/runner/work/primitives/primitives/dist/styleLint/functional/themes/light-high-contrast.json	2026-06-12 17:11:06.593557151 +0000
@@ -39283,6 +39283,7 @@
     },
     "org.primer.overrides": {
       "dark": "#844ae7",
+        "dark-protanopia-deuteranopia": "#454c54",
       "dark-high-contrast": "#D3ABFF",
       "dark-dimmed-high-contrast": "#e0c5ff",
       "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39313,6 +39314,7 @@
       },
       "org.primer.overrides": {
         "dark": "{base.color.purple.4}",
+          "dark-protanopia-deuteranopia": "{base.color.neutral.10}",
         "dark-high-contrast": "#D3ABFF",
         "dark-dimmed-high-contrast": "{base.color.purple.1}",
         "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39922,6 +39924,9 @@
         "web": "var(--fgColor-upsell)"
       }
     },
+      "org.primer.overrides": {
+        "dark-protanopia-deuteranopia": "#844ae7"
+      },
     "org.primer.llm": {
       "usage": ["upsell-text", "premium-text", "promotional"],
       "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."
@@ -39942,6 +39947,9 @@
           "web": "var(--fgColor-upsell)"
         }
       },
+        "org.primer.overrides": {
+          "dark-protanopia-deuteranopia": "{base.color.purple.4}"
+        },
       "org.primer.llm": {
         "usage": ["upsell-text", "premium-text", "promotional"],
         "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."

/styleLint/functional/themes/light-tritanopia-high-contrast.json

+++ /home/runner/work/primitives/primitives/dist/styleLint/functional/themes/light-tritanopia-high-contrast.json	2026-06-12 17:11:00.876358013 +0000
@@ -39285,6 +39285,7 @@
     },
     "org.primer.overrides": {
       "dark": "#844ae7",
+        "dark-protanopia-deuteranopia": "#454c54",
       "dark-high-contrast": "#D3ABFF",
       "dark-dimmed-high-contrast": "#e0c5ff",
       "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39315,6 +39316,7 @@
       },
       "org.primer.overrides": {
         "dark": "{base.color.purple.4}",
+          "dark-protanopia-deuteranopia": "{base.color.neutral.10}",
         "dark-high-contrast": "#D3ABFF",
         "dark-dimmed-high-contrast": "{base.color.purple.1}",
         "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39924,6 +39926,9 @@
         "web": "var(--fgColor-upsell)"
       }
     },
+      "org.primer.overrides": {
+        "dark-protanopia-deuteranopia": "#844ae7"
+      },
     "org.primer.llm": {
       "usage": ["upsell-text", "premium-text", "promotional"],
       "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."
@@ -39944,6 +39949,9 @@
           "web": "var(--fgColor-upsell)"
         }
       },
+        "org.primer.overrides": {
+          "dark-protanopia-deuteranopia": "{base.color.purple.4}"
+        },
       "org.primer.llm": {
         "usage": ["upsell-text", "premium-text", "promotional"],
         "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."

/styleLint/functional/themes/light-tritanopia.json

+++ /home/runner/work/primitives/primitives/dist/styleLint/functional/themes/light-tritanopia.json	2026-06-12 17:10:58.898222743 +0000
@@ -39279,6 +39279,7 @@
     },
     "org.primer.overrides": {
       "dark": "#a475f9",
+        "dark-protanopia-deuteranopia": "#454c54",
       "dark-high-contrast": "#D3ABFF",
       "dark-dimmed-high-contrast": "#ecd8ff",
       "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39309,6 +39310,7 @@
       },
       "org.primer.overrides": {
         "dark": "{base.color.purple.4}",
+          "dark-protanopia-deuteranopia": "{base.color.neutral.10}",
         "dark-high-contrast": "#D3ABFF",
         "dark-dimmed-high-contrast": "{base.color.purple.1}",
         "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39918,6 +39920,9 @@
         "web": "var(--fgColor-upsell)"
       }
     },
+      "org.primer.overrides": {
+        "dark-protanopia-deuteranopia": "#a475f9"
+      },
     "org.primer.llm": {
       "usage": ["upsell-text", "premium-text", "promotional"],
       "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."
@@ -39938,6 +39943,9 @@
           "web": "var(--fgColor-upsell)"
         }
       },
+        "org.primer.overrides": {
+          "dark-protanopia-deuteranopia": "{base.color.purple.4}"
+        },
       "org.primer.llm": {
         "usage": ["upsell-text", "premium-text", "promotional"],
         "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."

/styleLint/functional/themes/light.json

+++ /home/runner/work/primitives/primitives/dist/styleLint/functional/themes/light.json	2026-06-12 17:10:56.925183895 +0000
@@ -39277,6 +39277,7 @@
     },
     "org.primer.overrides": {
       "dark": "#a475f9",
+        "dark-protanopia-deuteranopia": "#454c54",
       "dark-high-contrast": "#D3ABFF",
       "dark-dimmed-high-contrast": "#ecd8ff",
       "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39307,6 +39308,7 @@
       },
       "org.primer.overrides": {
         "dark": "{base.color.purple.4}",
+          "dark-protanopia-deuteranopia": "{base.color.neutral.10}",
         "dark-high-contrast": "#D3ABFF",
         "dark-dimmed-high-contrast": "{base.color.purple.1}",
         "dark-protanopia-deuteranopia-high-contrast": "#D3ABFF",
@@ -39916,6 +39918,9 @@
         "web": "var(--fgColor-upsell)"
       }
     },
+      "org.primer.overrides": {
+        "dark-protanopia-deuteranopia": "#a475f9"
+      },
     "org.primer.llm": {
       "usage": ["upsell-text", "premium-text", "promotional"],
       "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."
@@ -39936,6 +39941,9 @@
           "web": "var(--fgColor-upsell)"
         }
       },
+        "org.primer.overrides": {
+          "dark-protanopia-deuteranopia": "{base.color.purple.4}"
+        },
       "org.primer.llm": {
         "usage": ["upsell-text", "premium-text", "promotional"],
         "rules": "Use for upgrade prompts and premium feature text. Do NOT use for regular content."

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Design Token Diff (Figma)

/figma/themes/dark-colorblind.json

+++ /home/runner/work/primitives/primitives/dist/figma/themes/dark-colorblind.json	2026-06-12 17:11:28.716270117 +0000
@@ -8412,15 +8412,15 @@
 {
   "name": "fgColor/done",
   "value": {
-      "r": 0.6705882352941176,
-      "g": 0.49019607843137253,
-      "b": 0.9725490196078431,
+      "r": 0.7176470588235294,
+      "g": 0.7411764705882353,
+      "b": 0.7843137254901961,
     "a": 1
   },
   "type": "COLOR",
   "description": "Text color for completed/done state indicators",
   "refId": "mode/fgColor/done",
-    "reference": "base/color/dark/base/color/purple/4",
+    "reference": "base/color/dark/base/color/neutral/10",
   "collection": "mode",
   "mode": "dark protanopia deuteranopia",
   "group": "semantic",
@@ -8440,7 +8440,7 @@
   "type": "COLOR",
   "description": "Text color for upsell and promotional content",
   "refId": "mode/fgColor/upsell",
-    "reference": "mode/fgColor/done",
+    "reference": "base/color/dark/base/color/purple/4",
   "collection": "mode",
   "mode": "dark protanopia deuteranopia",
   "group": "semantic",

@github-actions github-actions Bot temporarily deployed to Preview (Storybook) June 11, 2026 22:07 Inactive
@liuliu-dev liuliu-dev added the update snapshots Update visual regression test snapshots label Jun 12, 2026
@github-actions github-actions Bot removed the update snapshots Update visual regression test snapshots label Jun 12, 2026
@github-actions github-actions Bot temporarily deployed to Preview (Storybook) June 12, 2026 17:12 Inactive
@janmaarten-a11y janmaarten-a11y merged commit 2627836 into main Jun 12, 2026
29 checks passed
@janmaarten-a11y janmaarten-a11y deleted the janmaarten-a11y/dark-pd-done-color-fix branch June 12, 2026 17:36
@primer primer Bot mentioned this pull request Jun 12, 2026
lukasoppermann added a commit that referenced this pull request Jun 15, 2026
The merge conflict resolution kept purple.4 from main (accessibility
fix PR #1402), but this PR expands the scale from 0-9 to 0-11, shifting
the step values. In the new scale purple.4 = #553098 (~27% lightness)
which fails contrast on dark backgrounds.

The PR's calibrated value was purple.7 = #AB7DF8 (~73% lightness)
which passes 4.5:1 contrast on dark backgrounds.

Structural additions from main are kept:
- dark-protanopia-deuteranopia: neutral.10 for fgColor.done
- fgColor.upsell dark-protanopia-deuteranopia override (updated to purple.7)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@janmaarten-a11y janmaarten-a11y self-assigned this Jun 19, 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.

3 participants