Skip to content

Conversation

@rezrah
Copy link
Collaborator

@rezrah rezrah commented Nov 5, 2025

Summary

Towards https://github.com/github/brand-marketing-design/issues/2585

Updates global typography primitives. Also propagates changes to React components that depend on them.

Also replaces Monospace typefaces with a custom, proprietary file that replaces system defaults.

ℹ️ File sizes for the new font files have increased due to the inclusion of a new opsz axes in Mona Sans's variable font (+55KB. The Mona Sans Mono font file also adds +90KB to the bundle. These will need further optimization in follow up PR's.

List of notable changes:

  • Updates Primitive weight and size properties to match the latest design specs
  • Update default visual styles in Text and Heading components
  • Updated all affected snapshots (most of them due to above)
  • Replaced Mona Sans variable fonts with latest pre-release version
  • Added Mona Sans Mono as a fixed width default typeface

➕ Other additions, such as differences between Figma and Code weights have been applied separately duirng an internal QA period. Refer to this board for more details.

What should reviewers focus on?

  • Are the new typographic specs correct across all viewports
  • Is there any noticeable regression, or incorrect implementation in Storybook or visual diffs.

Steps to test:

  1. Storybook preview link (compare side-by-side with production for before/after)
  1. Use visual diffs in PR view to make side-by-side comparison easier

Supporting resources (related issues, external links, etc):

Contributor checklist:

  • All new and existing CI checks pass
  • Tests prove that the feature works and covers both happy and unhappy paths
  • Any drop in coverage, breaking changes or regressions have been documented above
  • UI Changes contain new visual snapshots (generated by adding update snapshots label to the PR)
  • All developer debugging and non-functional logging has been removed
  • Related issues have been referenced in the PR description

Reviewer checklist:

  • Check that pull request and proposed changes adhere to our contribution guidelines and code of conduct
  • Check that tests prove the feature works and covers both happy and unhappy paths
  • Check that there aren't other open Pull Requests for the same update/change

Screenshots:

Please try to provide before and after screenshots or videos

Before After
Screenshot 2025-11-13 at 10 36 11 Screenshot 2025-11-13 at 10 35 56
Before After
Screenshot 2025-11-13 at 10 35 20 Screenshot 2025-11-13 at 10 35 36
Before After
Screenshot 2025-11-13 at 10 35 10 Screenshot 2025-11-13 at 10 34 42

@changeset-bot
Copy link

changeset-bot bot commented Nov 5, 2025

🦋 Changeset detected

Latest commit: 525b04d

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

This PR includes changesets to release 7 packages
Name Type
@primer/react-brand Minor
@primer/brand-primitives Minor
@primer/brand-css Minor
@primer/brand-e2e Minor
@primer/brand-fonts Minor
@primer/brand-config Minor
@primer/brand-storybook 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

@github-actions
Copy link
Contributor

github-actions bot commented Nov 5, 2025

🔍 Design token changes found

View CSS variable changes
- --base-text-weight-normal: 450;
+ --base-text-weight-normal: 400;
+ --base-text-weight-regular: 400;
- --brand-text-letterSpacing-1000: -0.03em;
+ --brand-text-letterSpacing-1000: 0;
- --brand-text-letterSpacing-900: -0.02em;
+ --brand-text-letterSpacing-900: 0;
- --brand-text-letterSpacing-800: -0.02em;
+ --brand-text-letterSpacing-800: 0;
- --brand-text-letterSpacing-700: -0.02em;
+ --brand-text-letterSpacing-700: 0;
- --brand-text-letterSpacing-600: -0.02em;
+ --brand-text-letterSpacing-600: 0;
- --brand-text-letterSpacing-500: -0.01em;
+ --brand-text-letterSpacing-500: 0;
- --brand-text-letterSpacing-400: 0em;
+ --brand-text-letterSpacing-400: 0;
- --brand-text-letterSpacing-350: 0em;
+ --brand-text-letterSpacing-350: 0.18px;
- --brand-text-letterSpacing-300: 0em;
+ --brand-text-letterSpacing-300: 0.18px;
- --brand-text-letterSpacing-200: 0em;
+ --brand-text-letterSpacing-200: 0.24px;
- --brand-text-letterSpacing-100: 0.02em;
+ --brand-text-letterSpacing-100: 0.21px;
- --brand-text-lineHeight-1000: 1.1;
+ --brand-text-lineHeight-1000: 1.149;
- --brand-text-lineHeight-900: 1.1;
+ --brand-text-lineHeight-900: 1.2;
- --brand-text-lineHeight-600: 1.2;
+ --brand-text-lineHeight-600: 1.3;
- --brand-text-lineHeight-400: 1.3;
+ --brand-text-lineHeight-400: 1.4;
- --brand-text-lineHeight-350: 1.3;
+ --brand-text-lineHeight-350: 1.5;
- --brand-text-weight-1000: var(--base-text-weight-bold);
+ --brand-text-weight-heavy: 550;
- --brand-text-weight-900: var(--base-text-weight-semibold);
+ --brand-text-weight-extrabold: 543;
- --brand-text-weight-800: var(--base-text-weight-semibold);
+ --brand-text-weight-bold: 537;
- --brand-text-weight-700: var(--base-text-weight-semibold);
+ --brand-text-weight-semibold: 525;
- --brand-text-weight-600: var(--base-text-weight-semibold);
+ --brand-text-weight-medium: 500;
- --brand-text-weight-500: var(--base-text-weight-semibold);
+ --brand-text-weight-normal: 400;
- --brand-text-weight-400: var(--base-text-weight-semibold);
+ --brand-text-weight-regular: 400;
- --brand-text-weight-350: var(--base-text-weight-semibold);
+ --brand-text-weight-light: 400;
+ --brand-text-weight-extralight: 400;
+ --brand-text-weight-1000: var(--base-text-weight-normal);
+ --brand-text-weight-900: var(--base-text-weight-normal);
+ --brand-text-weight-800: var(--base-text-weight-normal);
+ --brand-text-weight-700: var(--base-text-weight-normal);
+ --brand-text-weight-600: var(--base-text-weight-normal);
+ --brand-text-weight-500: var(--base-text-weight-normal);
+ --brand-text-weight-400: var(--base-text-weight-normal);
+ --brand-text-weight-350: var(--base-text-weight-normal);
- --brand-text-subhead-weight-large: var(--base-text-weight-semibold);
+ --brand-text-subhead-weight-large: 475;
- --brand-text-subhead-weight-medium: var(--base-text-weight-semibold);
+ --brand-text-subhead-weight-medium: 550;
+ --brand-text-subhead-letterSpacing-large: 0.1px;
+ --brand-text-subhead-letterSpacing-medium: 0.24px;
- --brand-heading-letterSpacing-1000: -0.03em;
+ --brand-heading-letterSpacing-1000: 0;
- --brand-heading-letterSpacing-900: -0.02em;
+ --brand-heading-letterSpacing-900: 0;
- --brand-heading-letterSpacing-800: -0.02em;
+ --brand-heading-letterSpacing-800: 0;
- --brand-heading-letterSpacing-700: -0.02em;
+ --brand-heading-letterSpacing-700: 0;
- --brand-heading-letterSpacing-600: -0.02em;
+ --brand-heading-letterSpacing-600: 0;
- --brand-heading-letterSpacing-500: -0.01em;
+ --brand-heading-letterSpacing-500: 0;
- --brand-heading-letterSpacing-400: -0.01em;
+ --brand-heading-letterSpacing-400: 0;
- --brand-heading-weight-1000: var(--base-text-weight-bold);
+ --brand-heading-weight-1000: 440;
- --brand-heading-weight-900: var(--base-text-weight-semibold);
+ --brand-heading-weight-900: 440;
- --brand-heading-weight-800: var(--base-text-weight-semibold);
+ --brand-heading-weight-800: 465;
- --brand-heading-weight-700: var(--base-text-weight-semibold);
+ --brand-heading-weight-700: 460;
- --brand-heading-weight-600: var(--base-text-weight-semibold);
+ --brand-heading-weight-600: 460;
- --brand-heading-weight-500: var(--base-text-weight-semibold);
+ --brand-heading-weight-500: 480;
- --brand-heading-weight-400: var(--base-text-weight-semibold);
+ --brand-heading-weight-400: 480;
- --brand-fontStack-monospace: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
+ --brand-fontStack-monospace: "Mona Sans Mono", monospace;
- --brand-text-letterSpacing-900: -0.03em;
+ --brand-text-lineHeight-1000: 1.08;
- --brand-text-lineHeight-1000: 1.05;
+ --brand-text-lineHeight-900: 1.2;
- --brand-text-lineHeight-900: 1.05;
+ --brand-text-lineHeight-800: 1.2;
- --brand-text-size-1000: 4rem;
+ --brand-text-size-1000: 3.5rem;
- --brand-text-size-800: 2.25rem;
+ --brand-text-size-800: 2.5rem;
- --brand-text-size-700: 2.25rem;
+ --brand-text-size-700: 2.125rem;
- --brand-text-size-600: 2rem;
+ --brand-text-size-600: 1.75rem;
+ --brand-text-size-500: 1.5rem;
+ --brand-text-size-400: 1.25rem;
+ --brand-text-subhead-weight-large: 525;
- --brand-heading-letterSpacing-900: -0.03em;
+ --brand-heading-weight-1000: 440;
+ --brand-heading-weight-900: 440;
+ --brand-heading-weight-800: 465;
+ --brand-heading-weight-700: 460;
- --brand-text-letterSpacing-800: -0.03em;
+ --brand-text-letterSpacing-1000: -0.035em;
- --brand-text-letterSpacing-700: -0.03em;
+ --brand-text-lineHeight-1000: 1.08;
- --brand-text-lineHeight-1000: 1;
+ --brand-text-lineHeight-900: 1.1;
- --brand-text-lineHeight-900: 1;
+ --brand-text-lineHeight-800: 1.18;
- --brand-text-lineHeight-500: 1.2;
+ --brand-text-lineHeight-500: 1.35;
- --brand-text-size-1000: 6rem;
+ --brand-text-size-1000: 4rem;
- --brand-text-size-900: 4.5rem;
+ --brand-text-size-900: 3.5rem;
- --brand-text-size-800: 4rem;
+ --brand-text-size-800: 3rem;
- --brand-text-size-700: 3rem;
+ --brand-text-size-700: 2.5rem;
- --brand-text-size-600: 2.5rem;
+ --brand-text-size-600: 2.125rem;
- --brand-text-size-500: 2rem;
+ --brand-text-size-500: 1.75rem;
- --brand-text-size-400: 1.5rem;
+ --brand-text-size-400: 1.375rem;
+ --brand-text-subhead-weight-large: 500;
- --brand-heading-letterSpacing-800: -0.03em;
+ --brand-heading-letterSpacing-1000: -0.014rem;
- --brand-heading-letterSpacing-700: -0.03em;
+ --brand-heading-weight-1000: 425;
+ --brand-heading-weight-900: 440;
+ --brand-heading-weight-800: 440;
+ --brand-heading-weight-700: 460;
- --brand-text-style-italic-10: 'ital' 10;
+ --brand-text-codeInline-size: 0.9285em;
- --brand-text-style-italic-9: 'ital' 9;
+ --brand-text-codeBlock-lineHeight: 1.5385;
- --brand-text-style-italic-8: 'ital' 8;
+ --brand-text-codeBlock-size: 0.8125rem;
- --brand-text-style-italic-7: 'ital' 7;
+ --brand-text-caption-lineHeight: 1.3333;
- --brand-text-style-italic-6: 'ital' 6;
+ --brand-text-caption-size: 0.75rem;
- --brand-text-style-italic-5: 'ital' 5;
+ --brand-text-body-lineHeight-small: 1.6666;
- --brand-text-style-italic-4: 'ital' 4;
+ --brand-text-body-lineHeight-medium: 1.4285;
- --brand-text-style-italic-3: 'ital' 3;
+ --brand-text-body-lineHeight-large: 1.5;
- --brand-text-style-italic-2: 'ital' 2;
+ --brand-text-body-size-small: 0.75rem;
- --brand-text-style-italic-1: 'ital' 1;
+ --brand-text-body-size-medium: 0.875rem;
- --brand-text-letterSpacing-1000: -0.03em;
+ --brand-text-body-size-large: 1rem;
- --brand-text-letterSpacing-900: -0.02em;
+ --brand-text-subtitle-lineHeight: 1.6;
- --brand-text-letterSpacing-800: -0.02em;
+ --brand-text-subtitle-size: 1.25rem;
- --brand-text-letterSpacing-700: -0.02em;
+ --brand-text-title-lineHeight-small: 1.5;
- --brand-text-letterSpacing-600: -0.02em;
+ --brand-text-title-lineHeight-medium: 1.6;
- --brand-text-letterSpacing-500: -0.01em;
+ --brand-text-title-lineHeight-large: 1.5;
- --brand-text-letterSpacing-400: -0.01em;
+ --brand-text-title-size-small: 1rem;
- --brand-text-lineHeight-1000: 1.1;
+ --brand-text-title-size-medium: 1.25rem;
- --brand-text-lineHeight-900: 1.1;
+ --brand-text-title-size-large: 2rem;
- --brand-text-lineHeight-800: 1.2;
+ --brand-text-display-lineHeight: 1.4;
- --brand-text-lineHeight-700: 1.2;
+ --brand-text-display-size: 2.5rem;
- --brand-text-lineHeight-600: 1.2;
+ --brand-text-display-lineBoxHeight: 1.4;
- --brand-text-lineHeight-500: 1.3;
+ --brand-fontStack-sansSerifDisplay: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif, 'Apple Color Emoji',
- --brand-fontStack-sansSerifAlt: 'Hubot Sans',-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Se
+ --brand-fontStack-sansSerif: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe
- --brand-fontStack-sansSerif: 'Mona Sans', 'MonaSansFallback',-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple C
+ --brand-fontStack-system: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI
- --brand-fontStack-system: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
+ --brand-text-codeInline-weight: var(--base-text-weight-normal);
- --brand-heading-fontFamily: var(--brand-fontStack-sansSerif);
+ --brand-text-codeBlock-weight: var(--base-text-weight-normal);
- --brand-body-fontFamily: var(--brand-fontStack-sansSerif);
+ --brand-text-caption-weight: var(--base-text-weight-normal);
+ --brand-text-body-weight: var(--base-text-weight-normal);
+ --brand-text-subtitle-weight: var(--base-text-weight-normal);
+ --brand-text-title-weight-small: var(--base-text-weight-semibold);
+ --brand-text-title-weight-medium: var(--base-text-weight-semibold);
+ --brand-text-title-weight-large: var(--base-text-weight-semibold);
+ --brand-text-display-weight: var(--base-text-weight-medium);
+ --brand-text-codeInline-shorthand: var(--brand-text-codeInline-weight) var(--brand-text-codeInline-size) var(--brand-fontStack-monospace);
+ --brand-text-codeBlock-shorthand: var(--brand-text-codeBlock-weight) var(--brand-text-codeBlock-size)/var(--brand-text-codeBlock-lineHeight) var(-
+ --brand-text-caption-shorthand: var(--brand-text-caption-weight) var(--brand-text-caption-size)/var(--brand-text-caption-lineHeight) var(--brand-f
+ --brand-text-body-shorthand-small: var(--brand-text-body-weight) var(--brand-text-body-size-small)/var(--brand-text-body-lineHeight-small) var(--b
+ --brand-text-body-shorthand-medium: var(--brand-text-body-weight) var(--brand-text-body-size-medium)/var(--brand-text-body-lineHeight-medium) var(
+ --brand-text-body-shorthand-large: var(--brand-text-body-weight) var(--brand-text-body-size-large)/var(--brand-text-body-lineHeight-large) var(--b
+ --brand-text-subtitle-shorthand: var(--brand-text-subtitle-weight) var(--brand-text-subtitle-size)/var(--brand-text-subtitle-lineHeight) var(--bra
+ --brand-text-title-shorthand-small: var(--brand-text-title-weight-small) var(--brand-text-title-size-small)/var(--brand-text-title-lineHeight-smal
+ --brand-text-title-shorthand-medium: var(--brand-text-title-weight-medium) var(--brand-text-title-size-medium)/var(--brand-text-title-lineHeight-m
+ --brand-text-title-shorthand-large: var(--brand-text-title-weight-large) var(--brand-text-title-size-large)/var(--brand-text-title-lineHeight-larg
+ --brand-text-display-shorthand: var(--brand-text-display-weight) var(--brand-text-display-size)/var(--brand-text-display-lineHeight) var(--brand-f

@github-actions
Copy link
Contributor

github-actions bot commented Nov 5, 2025

⚠️ Visual differences found

Our visual comparison tests found UI differences.

Please review the differences by using the test artifacts to ensure that the changes were intentional.

Artifacts can be downloaded and reviewed locally.

Download links are available at the bottom of the workflow summary screen.

Example:

artifacts section of workflow run

If the changes are expected, please run npm run test:visual:update-snapshots to replace the previous fixtures.

Review visual differences

@github-actions
Copy link
Contributor

github-actions bot commented Nov 7, 2025

🟢 Unit test coverage changes found

Unit test coverage has been updated through this PR.

Changes: 0 new tests, 0 removed tests, 2 improved, 0 decreased

Component/Hook Statements Functions Branches Change
Heading 93.5% 100.0% 88.9% 89.5% +0.6%
RiverAccordion 93.2% 100.0% 59.1% 61.9% +2.8%

@rezrah rezrah marked this pull request as ready for review November 13, 2025 10:39
@rezrah rezrah requested a review from a team as a code owner November 13, 2025 10:39
Copilot AI review requested due to automatic review settings November 13, 2025 10:39
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR updates global typography primitives to align with new design specifications, affecting font weights, sizes, line heights, and letter spacing across the design system. The changes propagate to React components and include comprehensive visual snapshot updates.

Key Changes:

  • Updated typography design tokens with numeric font-weight values (410-550) replacing generic references
  • Adjusted type scales making larger heading sizes smaller on wide viewports
  • Added Mona Sans Mono font face for monospace text
  • Removed flaky ActionMenu visual regression test

Reviewed Changes

Copilot reviewed 9 out of 3299 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/design-tokens/src/tokens/functional/typography/typography.json Removed old typography token definitions (entire file deleted)
packages/design-tokens/src/tokens/functional/typography/typography-responsive.json Updated with new numeric font weights, adjusted sizes, line heights, and letter spacing values
packages/design-tokens/src/tokens/base/typography/typography.json Added regular weight token (400)
packages/design-tokens/src/formats/responsive-media-query.js Fixed media query formatter to handle numeric values and sort breakpoints correctly
packages/fonts/fonts.css Updated font sources and added Mona Sans Mono font face
packages/react/src/ActionMenu/ActionMenu.visual.spec.ts Removed flaky single-selection-small-open test
packages/e2e/scripts/playwright/playwright.generate-tests.ts Updated test configuration, skipping flaky test and adjusting timeout
.changeset/large-cherries-clean.md Documented all design token changes for @primer/brand-primitives
.changeset/green-laws-provide.md Documented component changes for @primer/react-brand

Copy link
Contributor

@joshfarrant joshfarrant left a comment

Choose a reason for hiding this comment

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

Nothing has jumped out at me from the docs or Storybook 👍

@simmonsjenna
Copy link

simmonsjenna commented Nov 13, 2025

@rezrah Here are some outliers I found. cc: @jesussandreas

For many instances (e.g. CTA copy, Breadcrumbs, Labels, Links, Form Labels, EyebrowBanner Heading, FAQ section Heading CTABanner and Bento Headings), we are still getting some font-weight overrides with this style:
font-weight: var(--base-text-weight-semibold)

CTAs:
Screenshot 2025-11-13 at 9 32 47 AM

Breadcrumbs:
Screenshot 2025-11-13 at 9 32 27 AM

Labels:
Screenshot 2025-11-13 at 9 32 15 AM

FAQ headline:
Screenshot 2025-11-13 at 9 53 22 AM

@rezrah
Copy link
Collaborator Author

rezrah commented Nov 14, 2025

Thanks for the feedback @simmonsjenna

The surface area of this work was initially scoped to Text and Heading compoennts, and not overrides in the React library, but in hindsight I agree that the overrides in our various internal components cause a noticable visual inbalance in practice, particularly at the 600+ weight range.

I've now updated all React components that previously applied a font-weight override of 600+ to use either 400 or 500. I've mostly eyeballed these, as there's no guidance on what they should be, besides Button which I can see is 500 now in @jesussandreas Brand Refactor updates. @simmonsjenna you can see all of my changes in this commit. Feel free to suggest alternatives if you have any preferences on final values...

Here's a quick diff to give a sense of these changes:

Buttons

Before After
Screenshot 2025-11-14 at 11 48 22 Screenshot 2025-11-14 at 13 38 41

Links

Before After
Screenshot 2025-11-14 at 10 30 08 Screenshot 2025-11-14 at 10 30 17

Stacked section intro items

Before
Screenshot 2025-11-14 at 10 11 40
After
Screenshot 2025-11-14 at 13 41 34

River breakout

Before
Screenshot 2025-11-14 at 10 10 58
After
Screenshot 2025-11-14 at 13 42 58

### River content

Before After
Screenshot 2025-11-14 at 10 09 29 Screenshot 2025-11-14 at 13 45 13

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.

5 participants