Rams MCP · The full engine, now in your coding agent
mui on GitHub

mui/material-ui

Reviewed against Rams quality heuristics: accessibility, color, typography, spacing, components, motion, UX, and craft.

30 files reviewed·August 1, 2026

View on GitHub

Elevated

Design risk in this codebase.

8issues
Critical, Serious & Moderate · top 5 shown below

Top fix

Add an accessible name to the icon-only theme toggle button

See the fix

Verdict

Visual polish outpaces basic usability: gradients and scrims got attention that alt text and focus states didn't. The biggest risk is that assistive tech users hit unlabeled controls and invisible focus, undermining an otherwise systemic design.

Files Rams reviewed

docs/src/pages/premium-themes/onepirate/modules/views/ProductHeroLayout.tsx

docs/src/pages/premium-themes/onepirate/modules/components/Button.tsx

docs/src/pages/premium-themes/onepirate/modules/components/Markdown.tsx

docs/src/pages/premium-themes/onepirate/modules/components/Paper.tsx

docs/src/pages/premium-themes/onepirate/modules/components/Snackbar.tsx

docs/src/pages/premium-themes/onepirate/modules/components/TextField.tsx

docs/src/pages/premium-themes/onepirate/modules/components/Typography.tsx

docs/src/pages/premium-themes/onepirate/modules/views/AppAppBar.tsx

docs/src/pages/premium-themes/onepirate/modules/views/AppFooter.tsx

docs/src/pages/premium-themes/onepirate/modules/views/ProductCTA.tsx

docs/src/pages/premium-themes/onepirate/modules/views/ProductCategories.tsx

docs/src/pages/premium-themes/onepirate/modules/views/ProductHero.tsx

docs/src/pages/premium-themes/onepirate/modules/views/ProductHowItWorks.tsx

docs/src/pages/premium-themes/onepirate/modules/views/ProductValues.tsx

examples/material-ui-pigment-css-nextjs-ts/src/app/page.tsx

docs/src/pages/premium-themes/onepirate/modules/components/AppBar.tsx

docs/src/pages/premium-themes/onepirate/modules/components/Toolbar.tsx

docs/src/pages/premium-themes/onepirate/modules/views/AppForm.tsx

docs/src/pages/premium-themes/onepirate/modules/views/ProductSmokingHero.tsx

packages-internal/core-docs/src/AppLayout/components/EditPage.tsx

examples/material-ui-nextjs-ts/src/app/about/page.tsx

examples/material-ui-nextjs-ts/src/app/layout.tsx

examples/material-ui-nextjs-ts/src/app/page.tsx

examples/material-ui-pigment-css-nextjs-ts/src/app/layout.tsx

examples/material-ui-remix-ts/app/src/Layout.tsx

docs/data/material/getting-started/templates/crud-dashboard/components/DashboardLayout.tsx

docs/src/pages/premium-themes/onepirate/ForgotPassword.tsx

docs/src/pages/premium-themes/onepirate/SignIn.tsx

docs/src/pages/premium-themes/onepirate/SignUp.tsx

docs/src/pages/premium-themes/onepirate/modules/form/FormFeedback.tsx

92/100

Accessibility

2 critical1 serious
AccessibilityCritical

examples/material-ui-pigment-css-nextjs-ts/src/app/page.tsx:40

Theme toggle button has no accessible name for screen readers

The IconButton at the top right of the hero swaps between "🌙" and "🔆" emoji as its only content, with no aria-label, title, or visually hidden text. Screen reader users hear "button" with no indication it toggles color scheme.

Why it matters

A screen reader user can't identify or operate the theme toggle at all, which locks them out of a control every sighted user can see and use.

Fix

Add an aria-label that describes the action the button performs.

<IconButton sx={{ fontSize: 20, px: 1.5 }} onClick={toggleColorScheme}>
  {colorScheme === 'light' ? '🌙' : '🔆'}
</IconButton>
<IconButton
  sx={{ fontSize: 20, px: 1.5 }}
  onClick={toggleColorScheme}
  aria-label={colorScheme === 'light' ? 'Switch to dark mode' : 'Switch to light mode'}
>
  {colorScheme === 'light' ? '🌙' : '🔆'}
</IconButton>
AccessibilityCritical

docs/src/pages/premium-themes/onepirate/modules/components/Button.tsx:12

Button strips its own focus ring with no replacement indicator

ButtonRoot sets boxShadow: 'none' as its base style, then reinforces it under '&:active, &:focus' with the same boxShadow: 'none'. Combined, keyboard focus produces zero visible change from the resting state.

Why it matters

A keyboard user tabbing through the page gets no visual confirmation this button is focused, so they can't tell where they are or whether Enter will activate it. This is a hard lockout for keyboard-only navigation.

Fix

Never remove focus-visible styling without substituting an equally visible replacement, such as an outline or ring.

'&:active, &:focus': {
    boxShadow: 'none',
  },
'&:active': {
    boxShadow: 'none',
  },
  '&:focus-visible': {
    outline: `2px solid ${theme.palette.primary.main}`,
    outlineOffset: 2,
  },
AccessibilitySerious

docs/src/pages/premium-themes/onepirate/modules/views/ProductHeroLayout.tsx:52

Hero image's alt text describes nothing about what it shows

The hero's leading <img> at the top of ProductHeroLayout has alt="wonder", a word describing a mood, not the image's content or purpose.

Why it matters

A screen reader user hears "wonder, image" with no way to know what's actually depicted, making the alt text functionally useless for anyone who can't see the image.

Fix

Write alt text that describes the image's actual content or the information it conveys, not an abstract mood word.

<img
  src="/static/themes/onepirate/productHeroWonder.png"
  alt="wonder"
  width="147"
  height="80"
/>
<img
  src="/static/themes/onepirate/productHeroWonder.png"
  alt="Decorative illustration of a pirate ship silhouette"
  width="147"
  height="80"
/>
96/100

Craft

2 serious
CraftSerious

examples/material-ui-pigment-css-nextjs-ts/src/app/page.tsx:66

Gradient text-clip on "Material UI" headline sacrifices legibility for effect

The span wrapping "Material UI" inside the h1 uses a diagonal gradient with WebkitBackgroundClip: 'text' and WebkitTextFillColor: 'transparent', producing a gradient-filled headline rather than a solid, high-contrast color.

Why it matters

Gradient-clipped text has no guaranteed contrast ratio against the page background across its own range, and it reads as a templated stock effect rather than an intentional brand decision.

Fix

Use a solid theme color for headline text and reserve gradients for backgrounds or decorative surfaces, not foreground text.

background: `linear-gradient(145deg, ${(theme.vars || theme).palette.primary.light} 5%, ${(theme.vars || theme).palette.primary.dark} 90%)`,
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
color: (theme.vars || theme).palette.primary.dark,
CraftSerious

docs/src/pages/premium-themes/onepirate/modules/views/ProductHeroLayout.tsx:74

Arrow-down image sizing uses invalid unitless string values

The arrow-down image's sx sets height: '16' and width: '12' as strings with no unit. CSS requires a numeric length or unit; a bare number string like '16' is not a valid CSS length and the browser drops the declaration.

Why it matters

Without valid height/width, the image falls back to its natural pixel size instead of the intended 16x12 scroll-cue size, so the visual the developer coded for never actually renders.

Fix

Pass numeric values (interpreted by MUI's sx as px) instead of unitless strings.

sx={{ height: '16', width: '12', position: 'absolute', bottom: 32 }}
sx={{ height: 16, width: 12, position: 'absolute', bottom: 32 }}

Typography

No issues found

Color

No issues found

Spacing

No issues found

Components

No issues found

Motion

No issues found

UX

No issues found

Working well

  • ProductHeroLayout's dark overlay Box at opacity: 0.5 sits behind the hero content as a deliberate scrim, guaranteeing legible contrast for text over an arbitrary background image rather than hoping the source photo is dark enough.
  • Button.tsx builds padding and font size from theme.spacing() and theme.typography.pxToRem() rather than hardcoded pixel values, keeping the component on the design system's scale so a token change propagates automatically.
  • The hero h1 uses fontSize: 'clamp(3rem, 2.354rem + 2.7562vw, 5rem)' paired with textWrap: 'balance', giving a display headline that scales fluidly across viewport widths and wraps cleanly without manual breakpoints.

Scored August 1, 2026 with Rams Engine v0.0.3 · Engine changelog
First scored July 29, 2026: 59/100. This rescore on v0.0.3: 59/100.

This page is an automated design review of mui/material-ui’s UI code: 30 files read against 291 versioned rules covering accessibility, color, typography, spacing, components, UX, motion, and craft. The score is out of 100; confirmed criticals cap it — one at 59, two at 49, three or more at 39.

More design scores

Score your own repo.

Free on public repos, no account. The same engine that scored this page reads your UI code and mints a score page like this one.

Public repos only. The full engine reviews the UI code and mints a public score page — we email you the link too. Already-scored repos open instantly.

Or get a design review on every pull requestInstall Rams