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

simstudioai/sim

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

30 files reviewed·August 1, 2026

View on GitHub

Top fix

Convert index header's raw pixel values to shared design tokens

See the fix

Verdict

A clean editorial layout undercut by unfinished edge cases: empty author pages, dead-end truncated text, and pixel values that dodge the design system. The core pattern is solid, but the last 10% of polish, states and consistency, was skipped.

Files Rams reviewed

apps/sim/app/(landing)/components/content-author-page/content-author-page.tsx

apps/sim/app/(landing)/components/content-index-page/content-index-page.tsx

apps/sim/app/(landing)/components/content-post-page/content-post-page.tsx

apps/sim/app/(landing)/components/content-tags-page/content-tags-page.tsx

apps/sim/app/(landing)/components/prose-page/prose-page.tsx

apps/sim/app/(landing)/components/solutions-page/solutions-page.tsx

apps/sim/app/workspace/[workspaceId]/components/credential-detail/components/credential-detail-layout.tsx

apps/sim/app/invite/components/layout.tsx

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/error/index.tsx

apps/sim/app/(auth)/components/auth-field.tsx

apps/sim/app/(auth)/components/auth-nav-prompt.tsx

apps/sim/app/(auth)/components/auth-shell.tsx

apps/sim/app/(auth)/components/auth-submit-button.tsx

apps/sim/app/(auth)/components/auth-text-link.tsx

apps/sim/app/(auth)/components/password-input.tsx

apps/sim/app/(auth)/components/social-login-buttons.tsx

apps/sim/app/(auth)/components/sso-login-button.tsx

apps/sim/app/(auth)/components/support-footer.tsx

apps/sim/app/(interfaces)/chat/components/auth/email/email-auth.tsx

apps/sim/app/(interfaces)/chat/components/auth/password/password-auth.tsx

apps/sim/app/(interfaces)/chat/components/header/header.tsx

apps/sim/app/(interfaces)/chat/components/input/input.tsx

apps/sim/app/(interfaces)/chat/components/input/voice-input.tsx

apps/sim/app/(interfaces)/chat/components/loading-state/loading-state.tsx

apps/sim/app/(interfaces)/chat/components/message-container/message-container.tsx

apps/sim/app/(interfaces)/chat/components/message/components/file-download.tsx

apps/sim/app/(interfaces)/chat/components/message/components/markdown-renderer.tsx

apps/sim/app/(interfaces)/chat/components/message/message.tsx

apps/sim/app/(interfaces)/components/interfaces-shell/interfaces-shell.tsx

apps/sim/app/(landing)/careers/components/job-board/job-board.tsx

98/100

Typography

1 serious
TypographySerious

apps/sim/app/(landing)/components/content-author-page/content-author-page.tsx:92

Clamped post description has no way for readers to see the rest

Each post row's description renders as `<p className='line-clamp-2 ...'>{p.description}</p>` with no `title` attribute, tooltip, or expand affordance. Any description longer than two lines is truncated with an ellipsis and permanently unreachable.

Why it matters

Readers scanning post summaries lose the second half of the description with no recovery path, which weakens their ability to judge whether the post is worth clicking.

Fix

Add a `title` attribute carrying the full description so truncated text remains accessible on hover/inspection.

<p className='line-clamp-2 text-[var(--text-muted)] text-sm leading-[150%]'>
                      {p.description}
                    </p>
<p
                      className='line-clamp-2 text-[var(--text-muted)] text-sm leading-[150%]'
                      title={p.description}
                    >
                      {p.description}
                    </p>
98/100

Components

1 serious
Design SystemSerious

apps/sim/app/(landing)/components/content-index-page/content-index-page.tsx:47

Index page header mixes raw pixel widths, padding, and font sizes

The header block uses `max-w-[1460px]`, `px-20`, `pt-[112px]`, and the `<h1>` uses `text-[28px]`/`leading-[100%]`/`lg:text-[40px]`, all arbitrary bracket values instead of the spacing/type scale. This same pattern repeats across the container in `content-author-page.tsx` and `content-post-page.tsx`.

Why it matters

Three content pages each hardcode their own version of the container width and heading size, so any future change to spacing or type rhythm has to be hunted down and edited in every file instead of one shared token.

Fix

Move repeated pixel values into shared container and type-scale classes so the three content-page layouts stay in sync.

<div className='mx-auto w-full max-w-[1460px] px-20 pt-[112px] max-sm:px-5 max-sm:pt-20 max-lg:px-8'>
          <div className='flex flex-col gap-4 md:flex-row md:items-end md:justify-between'>
            <h1 className='text-balance text-[28px] text-[var(--text-primary)] leading-[100%] tracking-[-0.02em] lg:text-[40px]'>
              {heading}
            </h1>
<div className='mx-auto w-full max-w-7xl px-20 pt-28 max-sm:px-5 max-sm:pt-20 max-lg:px-8'>
          <div className='flex flex-col gap-4 md:flex-row md:items-end md:justify-between'>
            <h1 className='text-balance text-3xl text-[var(--text-primary)] leading-none tracking-tight lg:text-5xl'>
              {heading}
            </h1>

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 free
98/100

UX

1 serious
UXSerious

apps/sim/app/(landing)/components/content-author-page/content-author-page.tsx:65

Author page shows an empty bordered box when an author has no posts

The posts list on the author page renders with `{posts.map((p) => (...))}` and no conditional for an empty array. If an author has zero published posts, the `border-x` container at line 64 renders with nothing inside it: no message, no link back to the section, just a blank frame.

Why it matters

A visitor lands on a bare, seemingly broken box with no explanation, and has no path forward except leaving the page.

Fix

Render an explicit empty state when the posts array is empty.

{posts.map((p) => (
              <div key={p.slug}>
{posts.length === 0 ? (
              <p className='p-6 text-[var(--text-muted)] text-sm'>No posts yet.</p>
            ) : (
              posts.map((p) => (
                <div key={p.slug}>

Accessibility

No issues found

Color

No issues found

Spacing

No issues found

Motion

No issues found

Craft

No issues found

Working well

  • The framed-list card pattern (border-x container, per-row divider, hover surface) matches the index/post pages, giving the author page a consistent shell instead of a bespoke layout.
  • The layout cleanly separates chrome (action bar, scroll container) from content slots via props, keeping callsites free of bespoke styling as the comment states.
  • The cover image, related-post cards, and share row all correctly carry alt text sourced from the post/author data instead of empty or missing alt attributes.
  • The featured post grid uses proper Next.js Image with fill, sizes, and priority tuned to the first three cards, showing real attention to LCP performance.

Scored August 1, 2026 with Rams Engine v0.0.3 · Engine changelog

This page is an automated design review of simstudioai/sim’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; any confirmed critical issue caps it at 59.

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