Rams MCP · The full engine, now in your coding agent
steven-tey on GitHub

steven-tey/precedent

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

25 files reviewed·July 9, 2026

Elevated

Design risk in this codebase.

6issues
Critical & Serious

Top fix

Add a reduced-motion fallback so hero content never stays invisible

See the fix

Verdict

Polished structure hides a hero that can vanish entirely for reduced-motion users and a badge that fails contrast against its own pill. The credit-where-due note: Clerk wrapping, Suspense boundaries, and lang attributes are all correctly in place, so this is a finishing problem, not an architecture problem.

Files Rams reviewed

app/layout.tsx

app/page.tsx

app/opengraph-image.tsx

components/home/card.tsx

components/home/component-grid.tsx

components/home/demo-modal.tsx

components/home/web-vitals.tsx

components/layout/navbar.tsx

components/shared/counting-numbers.tsx

components/shared/icons/buymeacoffee.tsx

components/shared/icons/expanding-arrow.tsx

components/shared/icons/github.tsx

components/shared/icons/google.tsx

components/shared/icons/loading-circle.tsx

components/shared/icons/loading-spinner.module.css

components/shared/modal.tsx

components/shared/popover.tsx

components/shared/tooltip.tsx

app/globals.css

components/shared/icons/index.tsx

components/layout/footer.tsx

components/shared/icons/loading-dots.module.css

components/shared/icons/loading-dots.tsx

components/shared/icons/loading-spinner.tsx

components/shared/icons/twitter.tsx

95/100

Color

1 critical1 serious
Color·app/page.tsx:35Critical

"Introducing Precedent" badge text fails contrast against its own pill

The `<Twitter>` icon and the "Introducing Precedent" text both use `text-[#1d9bf0]` on the pill's `bg-blue-100` background.

Why it matters

Blending #1d9bf0 against #dbeafe computes to roughly 2.5:1, well under the 4.5:1 AA floor for text this size (14px). The first thing on the page is nearly unreadable for low-vision users.

Fix

Darken the text color on light backgrounds until the ratio clears 4.5:1.

<Twitter className="h-5 w-5 text-[#1d9bf0]" />
<p className="text-sm font-semibold text-[#1d9bf0]">
  Introducing Precedent
</p>
<Twitter className="h-5 w-5 text-blue-700" />
<p className="text-sm font-semibold text-blue-700">
  Introducing Precedent
</p>
Color·app/opengraph-image.tsx:22Serious

Background gradient mixes indigo and cyan while heading mixes black and stone

The card runs three unrelated hues in one composition: `#E0E7FF` (indigo), `#CFFAFE` (cyan) on the backdrop, and `#000000` to `#78716c` (stone) on the heading text.

Why it matters

Three disconnected color families in a single 1200x630 card reads as unedited rather than a deliberate brand mark, and it's the first visual impression anyone gets when the link is shared on social platforms.

Fix

Pick one hue family for the backdrop and keep the heading gradient monochrome or on the same hue so the card reads as one composition.

backgroundImage:
  "linear-gradient(to bottom right, #E0E7FF 25%, #ffffff 50%, #CFFAFE 75%)",
backgroundImage:
  "linear-gradient(to bottom right, #EEF2FF 25%, #ffffff 50%, #E0E7FF 75%)",
96/100

Accessibility

2 serious
Accessibility·app/layout.tsx:24Serious

No skip-to-content link forces keyboard users through the nav on every page

The body renders `<Navbar />` then `<main>` directly with no landmark bypass. Keyboard and screen-reader users must tab through every nav item before reaching page content on every single route.

Why it matters

Every keyboard-only visitor pays this tax on every page load, which compounds across a multi-page app and is one of the most cited WCAG 2.4.1 failures in production sites.

Fix

Add a visually-hidden skip link at the top of body that jumps focus to the main landmark.

<body className={cx(sfPro.variable, inter.variable)}>
<body className={cx(sfPro.variable, inter.variable)}>
  <a href="#main-content" className="sr-only focus:not-sr-only focus:absolute focus:z-50 focus:p-4">Skip to content</a>
Accessibility·app/page.tsx:58Serious

"Deploy to Vercel" primary CTA has a sub-40px tap target

The "Deploy to Vercel" link uses `px-5 py-2`, giving roughly 8px of vertical padding on each side around a 14px line, for a total control height near 36px.

Why it matters

This is the page's primary conversion action; under ~40px it's harder to hit reliably on mobile and sits below the AAA 44px guidance for primary actions.

Fix

Increase vertical padding on the primary CTA so the hit area reaches at least 44px.

className="group flex max-w-fit items-center justify-center space-x-2 rounded-full border border-black bg-black px-5 py-2 text-sm text-white transition-colors hover:bg-white hover:text-black"
className="group flex max-w-fit items-center justify-center space-x-2 rounded-full border border-black bg-black px-5 py-3 text-sm text-white transition-colors hover:bg-white hover:text-black"

Want this on your repo?

Rams reviews your next PR automatically and posts inline fix suggestions.

Review my public repo for free
97/100

Motion

1 critical
Motion·app/page.tsx:41Critical

Hero content stays permanently invisible for reduced-motion users

The badge, "Building blocks for your Next project" heading, subhead, and CTA row all start at `opacity-0` and rely on the `animate-fade-up` keyframe plus `animationFillMode: "forwards"` to reveal themselves. There is no `prefers-reduced-motion` guard anywhere in the file or a `motion-safe:` prefix on these classes.

Why it matters

Users with `prefers-reduced-motion` enabled never trigger the animation, so the elements sit at opacity 0 forever: the entire hero, including the primary CTAs, is invisible to them.

Fix

Gate entrance animations behind motion-safe so reduced-motion users see full-opacity content immediately.

className="animate-fade-up bg-gradient-to-br from-black to-stone-500 bg-clip-text text-center font-display text-4xl font-bold tracking-[-0.02em] text-transparent opacity-0 drop-shadow-sm [text-wrap:balance] md:text-7xl md:leading-[5rem]"
className="motion-safe:animate-fade-up bg-gradient-to-br from-black to-stone-500 bg-clip-text text-center font-display text-4xl font-bold tracking-[-0.02em] text-transparent opacity-100 motion-safe:opacity-0 drop-shadow-sm [text-wrap:balance] md:text-7xl md:leading-[5rem]"
98/100

Typography

1 serious
Typography·components/home/card.tsx:23Serious

Heading drops from bold to normal weight exactly as it gets bigger on desktop

The `<h2>` for {title} is `text-xl font-bold` on mobile but switches to `md:text-3xl md:font-normal` on desktop. Weight and size move in opposite directions across the breakpoint.

Why it matters

The heading is the card's entry point; losing weight right as it gets larger flattens the emphasis instead of reinforcing it, so the title reads less confident on wider screens where it should read stronger.

Fix

Keep heading weight consistent across breakpoints; scale size only.

<h2 className="bg-gradient-to-br from-black to-stone-500 bg-clip-text font-display text-xl font-bold text-transparent [text-wrap:balance] md:text-3xl md:font-normal">
<h2 className="bg-gradient-to-br from-black to-stone-500 bg-clip-text font-display text-xl font-bold text-transparent text-balance md:text-3xl">

Spacing

No issues found

Components

No issues found

UX

No issues found

Craft

No issues found

Working well

  • "Deploy to Vercel" (solid black fill, white text) and "Star on GitHub" (white fill, gray border and text) are clearly differentiated by weight, not just color: the filled button reads as the committed action, the outlined one as secondary. This is exactly how a two-CTA row should split hierarchy.
  • The markdown link override styles `<a>` as `font-medium text-gray-800 underline`, clearly distinct from the surrounding `text-gray-500` body copy. This works because a link needs a visibly different weight and color from prose text so it reads as clickable without relying on hover alone.
  • The `large` prop on the feature grid's first `Card` ("Beautiful, reusable components") breaks the monotony of an otherwise uniform 3-column grid by giving the lead feature more visual room, so the eye has a clear entry point into the section instead of six identical tiles.
  • Layout classes (`rounded-xl`, `shadow-md`, `mx-auto`, `max-w-lg`) all come from Tailwind's standard scale rather than bracket values, which keeps this card's spacing and radius consistent with the rest of a token-based system.

Score your own repo with Rams.

Free on public repos. Rams reviews every pull request for accessibility, color, type, spacing, components, motion, UX, and craft, and posts inline fixes.