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

openstatushq/openstatus

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

30 files reviewed·July 9, 2026

Top fix

Replace bare `return null` states with visible loading and error UI

See the fix

Verdict

Solid token discipline collapses at the edges: every loading, error, or empty state just renders blank instead of designed feedback. The biggest risk is users mistaking a legitimate empty or failed state for a broken app.

Files Rams reviewed

apps/dashboard/src/app/(dashboard)/status-pages/[id]/components/layout.tsx

apps/dashboard/src/app/(dashboard)/status-pages/[id]/components/page.tsx

apps/web/src/app/(landing)/play/cdn-checker/components/monitor-cta.tsx

apps/web/src/app/(landing)/play/cdn-checker/components/results-table.tsx

apps/web/src/app/(landing)/play/cdn-checker/components/summary-card.tsx

apps/dashboard/src/app/(dashboard)/agents/page.tsx

apps/dashboard/src/app/(dashboard)/chat/layout.tsx

apps/dashboard/src/app/(dashboard)/cli/page.tsx

apps/dashboard/src/app/(dashboard)/layout.tsx

apps/dashboard/src/app/(dashboard)/monitors/[id]/incidents/layout.tsx

apps/dashboard/src/app/(dashboard)/monitors/[id]/incidents/page.tsx

apps/dashboard/src/app/(dashboard)/monitors/[id]/layout.tsx

apps/dashboard/src/app/(dashboard)/monitors/create/page.tsx

apps/dashboard/src/app/(dashboard)/overview/layout.tsx

apps/dashboard/src/app/(dashboard)/overview/page.tsx

apps/dashboard/src/app/(dashboard)/settings/(list)/page.tsx

apps/dashboard/src/app/(dashboard)/settings/account/page.tsx

apps/dashboard/src/app/(dashboard)/settings/general/layout.tsx

apps/dashboard/src/app/(dashboard)/settings/general/page.tsx

apps/dashboard/src/app/(dashboard)/settings/integrations/layout.tsx

apps/dashboard/src/app/(dashboard)/settings/integrations/page.tsx

apps/dashboard/src/app/(dashboard)/settings/private-locations/layout.tsx

apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/layout.tsx

apps/dashboard/src/app/(dashboard)/status-pages/[id]/layout.tsx

apps/dashboard/src/app/(dashboard)/status-pages/[id]/maintenances/layout.tsx

apps/dashboard/src/app/(dashboard)/status-pages/[id]/maintenances/page.tsx

apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx

apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/layout.tsx

apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx

apps/dashboard/src/app/(dashboard)/status-pages/[id]/subscribers/page.tsx

94/100

Accessibility

3 serious
Accessibility·apps/web/src/app/(landing)/play/cdn-checker/components/monitor-cta.tsx:71Serious

"Monitor this URL" link opens a new tab with no warning to screen reader users

The `<a>` labeled "Monitor this URL" sets `target="_blank" rel="noreferrer"` but the accessible name is only the visible text, with no indication the link leaves the current tab.

Why it matters

Screen reader and keyboard users get no warning before losing their place in the flow to a new tab, which breaks the expected back-navigation and disorients anyone not watching the browser chrome.

Fix

Add visually-hidden text (or an aria-label suffix) announcing that the link opens in a new tab.

  Monitor this URL
</a>
  Monitor this URL
  <span className="sr-only"> (opens in a new tab)</span>
</a>
Accessibility·apps/web/src/app/(landing)/play/cdn-checker/components/results-table.tsx:136Serious

Three table headers are empty, leaving icon and details columns unnamed

The header row has `<th className="w-12" />` three times for the provider icon, cache-status, and details columns, only "Region" and "Latency" carry visible header text.

Why it matters

Screen reader users navigating the table by column header hear nothing for three of the five columns, so the meaning of each icon and the details control is lost outside of visual context.

Fix

Give every header cell an accessible name, using visually-hidden text where a visual label isn't wanted.

<th className="w-12" />
<th className="w-12" />
<th>Region</th>
<th className="text-right!">Latency</th>
<th className="w-12" />
<th className="w-12"><span className="sr-only">Provider</span></th>
<th className="w-12"><span className="sr-only">Cache status</span></th>
<th>Region</th>
<th className="text-right!">Latency</th>
<th className="w-12"><span className="sr-only">Details</span></th>
Accessibility·apps/dashboard/src/app/(dashboard)/agents/page.tsx:60Serious

Decorative Info icon in the paid-feature note is unlabeled noise for screen readers

The upgrade note renders `<Info />` directly beside the text "This is a paid feature. Upgrade your plan to use the Slack agent." with no `aria-hidden` on the icon.

Why it matters

Screen readers announce the icon as "image" or its raw SVG name right before reading the sentence, adding noise that duplicates the adjacent label and slows comprehension for assistive-tech users.

Fix

Mark purely decorative icons sitting next to their own text label as aria-hidden.

<Note color="info" size="sm">
  <Info />
  This is a paid feature. Upgrade your plan to use the Slack agent.
</Note>
<Note color="info" size="sm">
  <Info aria-hidden="true" />
  This is a paid feature. Upgrade your plan to use the Slack agent.
</Note>
94/100

UX

3 serious
UX·apps/dashboard/src/app/(dashboard)/status-pages/[id]/components/page.tsx:20Serious

Page goes completely blank while loading or on fetch failure

The component returns `null` whenever `statusPage` is falsy: `if (!statusPage) return null;`. This covers the initial loading state, a failed query, and a not-found id with the exact same blank screen.

Why it matters

Users clicking into a status page's components tab see nothing rendered, with no way to tell if the page is loading, failed to load, or doesn't exist. There's no feedback and no recovery path.

Fix

Render distinct loading and error states instead of a silent null return.

if (!statusPage) return null;
const { data: statusPage, isLoading, error } = useQuery(
  trpc.page.get.queryOptions({ id: Number.parseInt(id) }),
);

if (isLoading) return <SectionGroup><Section>Loading...</Section></SectionGroup>;
if (error || !statusPage) return <SectionGroup><Section>Couldn't load this page. <button onClick={() => location.reload()}>Try again</button></Section></SectionGroup>;
UX·apps/web/src/app/(landing)/play/cdn-checker/components/summary-card.tsx:21Serious

Card vanishes entirely instead of showing a designed empty or loading state

`SummaryCard` returns `null` whenever `summary` is falsy: `if (!summary) return null;`. There's no skeleton, spinner, or placeholder message shown while a check is running or before one has been triggered.

Why it matters

Users see a gap where the card should be with no signal that anything is happening, which reads as a broken page rather than a pending state.

Fix

Render a designed placeholder (skeleton or waiting message) instead of returning null.

if (!summary) return null;
if (!summary) {
  return (
    <div className="border-border text-muted-foreground grid gap-4 border p-4 text-sm sm:grid-cols-3">
      Waiting for check results…
    </div>
  );
}
UX·apps/web/src/app/(landing)/play/cdn-checker/components/results-table.tsx:145Serious

Empty results row shows blank `<br />` cells with no message to the user

When `successRows.length === 0`, the table renders one `<tr>` whose last three cells contain only `<br />` tags, no text, no explanation of whether the check is running, failed, or returned nothing.

Why it matters

Users see an unlabeled row of icons next to blank space and have no way to tell if the tool is broken, still loading, or genuinely found no successful regions, which stalls their next action.

Fix

Replace the blank filler cells with a designed empty/loading state that names what happened and what to do next.

<tr>
  <td>
    <IconCloudProvider
      provider="globe"
      className="text-muted-foreground size-4"
    />
  </td>
  <td>
    <div className="bg-muted-foreground size-4" />
  </td>
  <td>
    <br />
  </td>
  <td>
    <br />
  </td>
  <td>
    <br />
  </td>
</tr>
<tr>
  <td colSpan={5} className="text-muted-foreground py-6 text-center text-sm">
    No successful checks yet.
  </td>
</tr>

Typography

No issues found

Color

No issues found

Spacing

No issues found

Components

No issues found

Motion

No issues found

Craft

No issues found

Working well

  • Status color comes from semantic tokens (`text-success`, `text-warning`, `text-destructive`, `border-border`) rather than hardcoded hex, and each colored value is still backed by the visible number or word itself ("18 / 20", "None") rather than color alone, so the state reads correctly even without color perception.
  • Reusing shared `Section`, `SectionHeader`, `SectionTitle`, `SectionDescription`, and `Note` primitives instead of one-off divs keeps this page's spacing and typography consistent with the rest of the dashboard, and means a future token or spacing change propagates here for free instead of drifting.
  • `CacheStatusLegend` renders the status name as visible text inside the colored swatch (`{status}` inside the colored div), which is exactly the right fallback: color plus a text label means colorblind users aren't locked out of the legend even though the row indicator itself skips this pattern.
  • The page orders its two sections correctly: "Slack agent" (setup and install) comes before "Messages" (usage examples), so a new user hits the action they need before the reference material. That sequencing matches how someone actually approaches the feature: set it up, then learn what to say.

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.