shadcn-ui/ui
Reviewed against Rams quality heuristics: accessibility, color, typography, spacing, components, motion, UX, and craft.
30 files reviewed·August 1, 2026
Low
Design risk in this codebase.
More findings
Verdict
A disciplined component system sits under a hero section that improvises its own type scale and colors. The biggest risk is the language selector vanishing below lg, a real functional gap dressed as a responsive choice.
Files Rams reviewed
apps/v4/app/(app)/examples/rtl/components/index.tsx
packages/shadcn/test/fixtures/frameworks/next-app-src/src/app/page.tsx
packages/shadcn/test/fixtures/frameworks/t3-app/src/app/page.tsx
apps/v4/app/(app)/(create)/components/accent-picker.tsx
apps/v4/app/(app)/(create)/components/action-menu.tsx
apps/v4/app/(app)/(create)/components/base-color-picker.tsx
apps/v4/app/(app)/(create)/components/base-picker.tsx
apps/v4/app/(app)/(create)/components/chart-color-picker.tsx
apps/v4/app/(app)/(create)/components/copy-preset.tsx
apps/v4/app/(app)/(create)/components/create-devtools.tsx
apps/v4/app/(app)/(create)/components/customizer.tsx
apps/v4/app/(app)/(create)/components/design-system-provider.tsx
apps/v4/app/(app)/(create)/components/font-picker.tsx
apps/v4/app/(app)/(create)/components/history-buttons.tsx
apps/v4/app/(app)/(create)/components/icon-library-picker.tsx
apps/v4/app/(app)/(create)/components/icon-placeholder.tsx
apps/v4/app/(app)/(create)/components/item-explorer.tsx
apps/v4/app/(app)/(create)/components/lock-button.tsx
apps/v4/app/(app)/(create)/components/main-menu.tsx
apps/v4/app/(app)/(create)/components/menu-picker.tsx
apps/v4/app/(app)/(create)/components/mode-switcher.tsx
apps/v4/app/(app)/(create)/components/open-preset.tsx
apps/v4/app/(app)/(create)/components/picker.tsx
apps/v4/app/(app)/(create)/components/preset-picker.tsx
apps/v4/app/(app)/(create)/components/preview-override.tsx
apps/v4/app/(app)/(create)/components/preview-switcher.tsx
apps/v4/app/(app)/(create)/components/preview.tsx
apps/v4/app/(app)/(create)/components/radius-picker.tsx
apps/v4/app/(app)/(create)/components/random-button.tsx
apps/v4/app/(app)/(create)/components/reset-button.tsx
Typography
packages/shadcn/test/fixtures/frameworks/t3-app/src/app/page.tsx:16
Arrow glyph in 'First Steps →' heading renders inconsistently across fonts
Both card headings, "First Steps →" and "Documentation →", append a raw "→" character straight into the h3 text. Because it's a font glyph rather than an icon, its stroke weight, size, and baseline shift with whatever font loads, and it reads to a screen reader as part of the link name with no semantic separation from the label.
Why it matters
The arrow is meant to signal 'this card is a link', but its rendering is unpredictable across fonts and it clutters the accessible name announced by assistive tech, degrading the affordance it's trying to add.
Fix
Wrap decorative glyphs in their own element with aria-hidden so they stay visually separate from the label and out of the accessible name.
<h3 className="text-2xl font-bold">First Steps →</h3><h3 className="text-2xl font-bold">First Steps <span aria-hidden="true">→</span></h3>packages/shadcn/test/fixtures/frameworks/t3-app/src/app/page.tsx:7
Hero heading breaks the type scale with an arbitrary 5rem size
The "Create T3 App" h1 uses text-5xl font-extrabold as a base and jumps to sm:text-[5rem], an arbitrary value that sits outside Tailwind's built-in scale (text-7xl is 4.5rem, text-8xl is 6rem).
Why it matters
A one-off size value that isn't on the scale means every future heading has to guess whether to match 5rem exactly or round to the nearest scale step, and the type system stops being a system.
Fix
Use the nearest standard scale step instead of an arbitrary bracket value.
<h1 className="text-5xl font-extrabold tracking-tight text-white sm:text-[5rem]"><h1 className="text-5xl font-extrabold tracking-tight text-white sm:text-8xl">UX
apps/v4/app/(app)/examples/rtl/components/index.tsx:47
Language selector disappears entirely below the lg breakpoint
The LanguageSelector controlling ar/he language toggle is set to hidden ... lg:flex with no alternate trigger anywhere else in the tree. Below the lg breakpoint, the element that lets a user switch between Arabic and Hebrew simply doesn't render.
Why it matters
Anyone viewing this RTL demo on a tablet or phone loses the only control that drives the page's core feature, the language switch, so the RTL behavior can't be tested or demoed on smaller viewports at all.
Fix
Provide a compact, always-visible variant of the control instead of hiding it below a breakpoint with no fallback.
className="absolute -top-12 right-52 hidden h-8! data-[size=sm]:rounded-lg lg:flex"className="absolute -top-12 right-4 flex h-8! data-[size=sm]:rounded-lg lg:right-52"Get this score on every PR.
Rams reviews each pull request on your repo and posts inline one-click fixes — about a minute per review.
Install Rams freeCraft
packages/shadcn/test/fixtures/frameworks/t3-app/src/app/page.tsx:5
Hero gradient uses raw hex values instead of reusable tokens
The main container sets bg-gradient-to-b from-[#2e026d] to-[#15162c] as arbitrary Tailwind values, and the "T3" span next to it uses text-[hsl(280,100%,70%)]. Three bespoke color values appear with no shared source.
Why it matters
Every future screen that wants this brand purple has to retype the same hex strings, so the palette drifts as soon as a second page is built and nobody can update the brand color from one place.
Fix
Move one-off arbitrary color values into a shared token (CSS variable or Tailwind theme color) and reference it by name.
<main className="flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#2e026d] to-[#15162c] text-white"><main className="flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-brand-950 to-brand-900 text-white">Accessibility
Color
Spacing
Components
Motion
Working well
- The Docs/Learn/Templates/Deploy card grid uses `motion-reduce:transform-none` on the hover-translate span, correctly respecting reduced-motion preferences for a purely decorative micro-interaction.
- Using data-accent with a Tailwind data attribute selector (data-[accent=bold]:fill-foreground) to drive icon fill state is a clean, CSS-only way to reflect state without extra JS.
- Disabling animation on the cmd-k palette (animate-none!) is correct: a keyboard-triggered command surface used dozens of times a day should open instantly, not fade in.
- The two feature cards ("First Steps" and "Documentation") share identical structure, padding, and hover treatment, giving the grid a consistent, intentional feel.
Scored August 1, 2026 with Rams Engine v0.0.3 · Engine changelog
First scored May 13, 2026: 81/100. This rescore on v0.0.3: 90/100.
This page is an automated design review of shadcn-ui/ui’s UI code: 30 files read against 308 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.