brand icon indicating copy to clipboard operation
brand copied to clipboard

[Brand Refactor] Type scale updates

Open rezrah opened this issue 2 months ago • 6 comments

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

rezrah avatar Nov 05 '25 14:11 rezrah

🦋 Changeset detected

Latest commit: 525b04d7e41d7638adbaccea133b4fa1502c77ea

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

changeset-bot[bot] avatar Nov 05 '25 14:11 changeset-bot[bot]

🔍 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[bot] avatar Nov 05 '25 14:11 github-actions[bot]

⚠️ 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[bot] avatar Nov 05 '25 14:11 github-actions[bot]

🟢 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%

github-actions[bot] avatar Nov 07 '25 11:11 github-actions[bot]

@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

simmonsjenna avatar Nov 13 '25 18:11 simmonsjenna

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

rezrah avatar Nov 14 '25 11:11 rezrah