From 671b32674de7616880d498717a2eaab8676caf1a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 12 Sep 2026 04:05:06 +0000 Subject: [PATCH] Primer branding: use color tokens in dark theme instead of hardcoded hex - Route every dark-mode CSS custom property through the same Primer CSS variable (--color-*) used in light mode, keeping the hardcoded hex as a fallback value only. primer_brand_review flagged hardcoded-hex as an off-brand pattern; light mode already did this correctly, dark mode did not. - Update the a11y contrast test regex to extract the hex fallback from var(--token, #hex) as well as bare hex values, since dark-theme vars now read var(--color-fg-default, #e6edf3) instead of #e6edf3. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/styles/style.css | 70 ++++++++++++++++++++++---------------------- test/a11y.test.js | 4 ++- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/styles/style.css b/src/styles/style.css index e841825..90e21e8 100644 --- a/src/styles/style.css +++ b/src/styles/style.css @@ -80,45 +80,45 @@ [data-color-mode="dark"] { color-scheme: dark; - --bg-primary: #0d1117; - --bg-secondary: #161b22; - --bg-tertiary: #21262d; - --bg-card: #161b22; - --bg-subtle: #161b22; - --bg-inset: #010409; - --text-primary: #e6edf3; - --text-secondary: #7d8590; - --text-muted: #8b949e; - --accent-blue: #4493f8; + --bg-primary: var(--color-canvas-default, #0d1117); + --bg-secondary: var(--color-canvas-subtle, #161b22); + --bg-tertiary: var(--color-neutral-subtle, #21262d); + --bg-card: var(--color-canvas-default, #161b22); + --bg-subtle: var(--color-canvas-subtle, #161b22); + --bg-inset: var(--color-canvas-inset, #010409); + --text-primary: var(--color-fg-default, #e6edf3); + --text-secondary: var(--color-fg-muted, #7d8590); + --text-muted: var(--color-fg-subtle, #8b949e); + --accent-blue: var(--color-accent-fg, #4493f8); --accent-blue-rgb: 68, 147, 248; - --accent-green: #3fb950; + --accent-green: var(--color-success-emphasis, #3fb950); --accent-green-rgb: 63, 185, 80; - --accent-green-solid: #238636; - --accent-green-hover: #2ea043; - --agent-purple: #ab7df8; - --agent-purple-dark: var(--color-done-emphasis, #8250df); + --accent-green-solid: var(--color-success-emphasis, #238636); + --accent-green-hover: var(--color-success-fg, #2ea043); + --agent-purple: var(--color-done-emphasis, #ab7df8); + --agent-purple-dark: var(--color-done-fg, #8250df); --agent-purple-rgb: 171, 125, 248; - --border-color: #30363d; - --border-default: #30363d; - --border-subtle: #21262d; - --border-hover: #6e7681; - --border-focus: #4493f8; - --code-bg: #010409; - --yaml-key: #79c0ff; - --yaml-value: #a5d6ff; - --yaml-string: #a5d6ff; - --yaml-comment: #8b949e; - --heading-color: #3fb950; - --success: #3fb950; - --warning: #d29922; - --danger: #f85149; + --border-color: var(--color-border-default, #30363d); + --border-default: var(--color-border-default, #30363d); + --border-subtle: var(--color-border-muted, #21262d); + --border-hover: var(--color-border-default, #6e7681); + --border-focus: var(--color-accent-fg, #4493f8); + --code-bg: var(--color-canvas-inset, #010409); + --yaml-key: var(--color-prettylights-syntax-constant, #79c0ff); + --yaml-value: var(--color-prettylights-syntax-string, #a5d6ff); + --yaml-string: var(--color-prettylights-syntax-string, #a5d6ff); + --yaml-comment: var(--color-prettylights-syntax-comment, #8b949e); + --heading-color: var(--color-success-fg, #3fb950); + --success: var(--color-success-fg, #3fb950); + --warning: var(--color-attention-fg, #d29922); + --danger: var(--color-danger-fg, #f85149); --header-gradient-start: rgba(1, 4, 9, 0.95); - --label-blue: #0969da; - --label-purple: #8250df; - --label-green: #1a7f37; - --label-orange: #e3833e; - --label-pink: #bf3989; - --label-gray: #656d76; + --label-blue: var(--color-accent-emphasis, #0969da); + --label-purple: var(--color-done-emphasis, #8250df); + --label-green: var(--color-success-emphasis, #1a7f37); + --label-orange: var(--color-severe-emphasis, #e3833e); + --label-pink: var(--color-sponsors-emphasis, #bf3989); + --label-gray: var(--color-neutral-emphasis, #656d76); /* dark-mode label-orange (#e3833e) needs dark text to meet contrast; light text fails */ --label-orange-fg: #1a1300; --shadow-card: 0 2px 8px rgba(1,4,9,0.4); diff --git a/test/a11y.test.js b/test/a11y.test.js index 4f3afd6..9bc86ed 100644 --- a/test/a11y.test.js +++ b/test/a11y.test.js @@ -63,7 +63,9 @@ describe('dark theme contrast', () => { } function darkVar(name) { - const match = darkThemeBody().match(new RegExp(`${name}:\\s*(#[0-9a-fA-F]{6})`)); + // Values may be a bare hex or a Primer CSS var with a hex fallback, e.g. + // `var(--color-fg-default, #e6edf3)` — match the last hex literal on the line either way. + const match = darkThemeBody().match(new RegExp(`${name}:[^;]*?(#[0-9a-fA-F]{6})[^;]*;`)); expect(match, `${name} not found in dark theme`).not.toBeNull(); return match[1]; }