Skip to content

fix: force font-normal for Hero font family to prevent browser synthesis#932

Draft
georgewrmarshall wants to merge 1 commit intomainfrom
fix/mmpoly-hero-font-weight
Draft

fix: force font-normal for Hero font family to prevent browser synthesis#932
georgewrmarshall wants to merge 1 commit intomainfrom
fix/mmpoly-hero-font-weight

Conversation

@georgewrmarshall
Copy link
Contributor

@georgewrmarshall georgewrmarshall commented Feb 23, 2026

Description

This PR implements a refined, constants-based architecture for font family weight constraints to fix the MMPoly Hero font rendering issue.

Problem: The MMPoly Hero font only has a regular weight (400) font file available, but the design system was applying font-weight 700 (bold) for Display variants on small screens. This forced browsers to artificially synthesize bold text, resulting in muddy/blurry rendering—especially noticeable on mobile displays and with uppercase content.

Solution - Constants-Based Architecture:

1. Single Source of Truth

Created FONT_FAMILY_AVAILABLE_WEIGHTS constant that documents which font weights are actually available for each font family.

2. Weight Override Constants

  • React Web: CLASSMAP_FONTFAMILY_WEIGHT_OVERRIDE maps to Tailwind classes
  • React Native: FONTFAMILY_WEIGHT_OVERRIDE maps to FontWeight enum values

3. Consistent Component Logic

Both platforms apply weight constraints with the same pattern in Text.constants.ts → Text.tsx

4. Additional Improvements

  • Removed font-normal from FontFamily.Hero enum (clean separation of concerns)
  • Removed duplicate @font-face declarations for MMPoly in Tailwind CSS
  • Added comprehensive "All Variants with Font Families" Storybook stories

Benefits

✅ Consistent cross-platform architecture
✅ Self-documenting (shows which weights exist)
✅ Scalable (easy to add constrained families)
✅ Type-safe with clear separation of concerns

Related issues

Fixes: #928

Manual testing steps

  1. Run yarn storybook (web) or yarn storybook:ios/android (native)
  2. Navigate to Components/Text → "All Variants with Font Families"
  3. Verify Hero Font Family section renders crisply without synthetic bolding
  4. Test on mobile viewport/device to confirm no blurry rendering

Pre-merge author checklist

  • Followed MetaMask Contributor Docs
  • Completed PR template
  • Included tests (Storybook stories)
  • Documented code with JSDoc
  • Applied labels (not external contributor)

Pre-merge reviewer checklist

  • Manually tested the PR
  • Confirms PR addresses all acceptance criteria

@github-actions
Copy link
Contributor

📖 Storybook Preview

Implements a consistent, constants-based architecture for font family weight constraints
to prevent browser font synthesis when unavailable weights are requested.

**Problem:** MMPoly Hero font only has regular weight (400) available, but design system
was applying bold (700) for Display variants, causing browsers to synthesize bold text
and producing muddy/blurry rendering on mobile and uppercase content.

**Solution - Constants-Based Architecture:**

1. **Single Source of Truth**: Created `FONT_FAMILY_AVAILABLE_WEIGHTS` constant mapping
   which documents available weights per font family

2. **Weight Override Constants**:
   - React Web: `CLASSMAP_FONTFAMILY_WEIGHT_OVERRIDE` maps to Tailwind classes
   - React Native: `FONTFAMILY_WEIGHT_OVERRIDE` maps to FontWeight enum values

3. **Consistent Implementation**: Both platforms now use the same architectural pattern:
   - Define constraints in Text.constants.ts
   - Apply constraints in Text.tsx component logic
   - Override takes precedence: fontFamily override → fontWeight prop → variant default

4. **Clean Enum**: Removed `font-normal` from `FontFamily.Hero` enum value, keeping
   enum semantically clean (family only, not weight)

5. **Tailwind CSS Cleanup**: Removed duplicate `@font-face` declarations for MMPoly
   weights 500/700 since only weight 400 exists

**Files Changed:**
- packages/design-system-react/src/types/index.ts
- packages/design-system-react/src/components/Text/Text.constants.ts
- packages/design-system-react/src/components/Text/Text.tsx
- packages/design-system-react-native/src/components/Text/Text.constants.ts
- packages/design-system-react-native/src/components/Text/Text.tsx
- apps/storybook-react/tailwind.css

**Benefits:**
- ✅ Consistent cross-platform architecture
- ✅ Self-documenting (shows which weights exist per family)
- ✅ Scalable (easy to add new constrained font families)
- ✅ Type-safe with clear separation of concerns

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@georgewrmarshall georgewrmarshall force-pushed the fix/mmpoly-hero-font-weight branch from 6725f81 to 7dba65c Compare February 23, 2026 22:13
@github-actions
Copy link
Contributor

📖 Storybook Preview

Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

}

/* MM Poly */
/* MM Poly - Only regular weight is available */
Copy link
Contributor

Choose a reason for hiding this comment

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

Removed MMPoly weights may re-enable synthesis

Medium Severity

Removing the @font-face entries for MMPoly weights 500 and 700 can reintroduce synthetic bold/medium rendering anywhere that uses font-family: MMPoly with non-400 font-weight outside the Text component override, potentially bringing back the blurriness this PR is addressing in Storybook (or any other direct CSS usage).

Fix in Cursor Fix in Web

],
[FontFamily.Accent]: [FontWeight.Regular, FontWeight.Medium, FontWeight.Bold],
[FontFamily.Hero]: [FontWeight.Regular], // Only regular weight available for MMPoly
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Unused exported available-weight constants

Low Severity

The new exported constant FONT_FAMILY_AVAILABLE_WEIGHTS is not referenced anywhere, which adds dead API surface and increases the chance future code incorrectly relies on it being enforced, even though the actual enforcement is done via CLASSMAP_FONTFAMILY_WEIGHT_OVERRIDE/FONTFAMILY_WEIGHT_OVERRIDE.

Additional Locations (1)

Fix in Cursor Fix in Web

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.

Bug: MMPoly font missing weight 700 causing faux-bold rendering with DisplayMd variant

1 participant