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

mirajchokshi/agentacta

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

2 files reviewed·July 22, 2026

View on GitHub

Elevated

Design risk in this codebase.

10issues
Critical, Serious & Moderate · top 6 shown below

Top fix

Convert sidebar nav divs into real, keyboard-accessible link or button elements

See the fix

Verdict

Polished chrome sits on top of a sidebar nav that keyboard and screen-reader users literally cannot use. The token system is sound in theory but leaks undefined variables and near-invisible text, so the biggest risk is that the most-used surface is also the most broken.

Files Rams reviewed

public/index.html

public/style.css

95/100

Color

1 critical1 serious
ColorCritical

public/style.css:26

Tertiary text color reads at ~2.4:1 on the surface background across a dozen labels

`--text-tertiary` (`#4a5568` in dark theme) is used at 10-11px on `.section-label`, `.config-label`, `.session-id-label`, `.confusion-label`, and `.signal-bar-count`, all sitting on `--bg-surface` (`#0f1420`). Computed contrast is ~2.4:1.

Why it matters

That's below the WCAG AA 4.5:1 floor for small text and even below the 3:1 large-text floor, so these labels are effectively unreadable for a large share of users in the default dark theme, and this token is reused all over the app.

Fix

Raise --text-tertiary's lightness until it clears 4.5:1 against --bg-surface, keeping its hue.

--text-tertiary: #4a5568;
--text-tertiary: #7b8798;
ColorSerious

public/style.css:407

Session project badge uses a one-off blue instead of the existing accent token

`.session-project` hardcodes `color: #7fb4ff` and `background: rgba(39, 94, 182, 0.18)`, while its siblings `.session-model`, `.session-agent`, and `.session-type` all correctly use `var(--purple)`/`var(--teal)`/`var(--amber)` plus their `-soft` background tokens.

Why it matters

A fourth, unrelated blue that doesn't match `--accent` (#6390f0) means the palette now has two competing blues, and this badge won't repaint correctly when the light/oled themes swap tokens.

Fix

Add a project-badge color to the token set (or reuse --accent) instead of a hardcoded one-off hex.

.session-project {
  font-size: 11px;
  font-weight: 500;
  color: #7fb4ff;
  background: rgba(39, 94, 182, 0.18);
  padding: 2px 10px;
  border-radius: 10px;
}
.session-project {
  font-size: 11px;
  font-weight: 500;
  color: var(--accent);
  background: var(--accent-soft);
  padding: 2px 10px;
  border-radius: 10px;
}
96/100

Components

2 serious
ComponentsSerious

public/index.html:60

Theme, settings, and mobile toolbar buttons sit below the 40px minimum hit area

`.theme-toggle` (used by `#theme-toggle` and `#settings-btn`) renders at 30x30px, and `.mobile-search-btn`/`.theme-toggle-mobile` (used by `#mobile-search-btn`, `#theme-toggle-mobile`, `#settings-btn-mobile`) render at 32x32px per style.css, with no padding-based hit-area extension in the markup.

Why it matters

These are the only controls for switching theme and reaching settings, and the mobile toolbar versions are the sole entry points on touch devices. Sub-40px targets increase mis-taps for touch and motor-impaired users right where the app is hardest to recover from a wrong tap.

Fix

Extend the hit area of small icon buttons with a pseudo-element or padding so the tappable region reaches at least 40x40px without changing the visible icon size.

<button class="mobile-search-btn" id="mobile-search-btn" title="Search" aria-label="Search"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg></button>
<button class="mobile-search-btn hit-area-40" id="mobile-search-btn" title="Search" aria-label="Search"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg></button>
ComponentsSerious

public/style.css:1002

Three CSS variables are referenced but never defined anywhere in the theme system

`.settings-gear`, `.insight-row:hover`, and `.insight-callout` reference `var(--text-muted)`, `var(--hover-bg)`, and `var(--border-color)`. None of these exist in `:root`, `[data-theme="light"]`, or `[data-theme="oled"]`: the file's real tokens are `--text-tertiary`, `--bg-hover`, and `--border-subtle`/`--border-default`.

Why it matters

An undefined custom property has no fallback, so the browser treats the declaration as invalid and the affected color/background never renders, silently breaking the gear icon color, the insight row hover state, and the callout divider across all three themes.

Fix

Point these declarations at the tokens the rest of the file already uses.

  color: var(--text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s, background 0.15s;
}
.settings-gear svg { width: 16px; height: 16px; }
.settings-gear:hover { color: var(--text-primary); background: var(--hover-bg); }
  color: var(--text-tertiary);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s, background 0.15s;
}
.settings-gear svg { width: 16px; height: 16px; }
.settings-gear:hover { color: var(--text-primary); background: var(--bg-hover); }

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
97/100

Accessibility

1 critical
AccessibilityCritical

public/index.html:35

Sidebar navigation items are unclickable divs, not keyboard-accessible controls

All five primary nav entries ("Overview", "Sessions", "Insights", "Timeline", "Files") are `<div class="nav-item" data-view="...">` elements with no `role`, no `tabindex`, and no keyboard handler visible in the markup. Only a mouse click (wired in app.js) can reach them.

Why it matters

Keyboard users and screen reader users cannot tab to or activate any section of the app. This is the entire navigation system, so it locks out an entire class of users from the product's core interaction.

Fix

Use semantic <button> elements for clickable navigation items so they get focus, keyboard activation, and the correct accessibility role for free.

<div class="nav-item active" data-view="overview">
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12h7V3H3z"/><path d="M14 21h7v-7h-7z"/><path d="M14 10h7V3h-7z"/><path d="M3 21h7v-5H3z"/></svg>
  <span>Overview</span>
</div>
<button type="button" class="nav-item active" data-view="overview" aria-current="page">
  <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12h7V3H3z"/><path d="M14 21h7v-7h-7z"/><path d="M14 10h7V3h-7z"/><path d="M3 21h7v-5H3z"/></svg>
  <span>Overview</span>
</button>
97/100

Motion

1 critical
MotionCritical

public/style.css:583

Three infinite animations run with no reduced-motion guard anywhere in the file

`skeletonShimmer` (skeleton loading), `pulse` (the `.loading::before` dot), and `jumpPulse` (`.jump-to-start-btn.jumping::after`) all run `infinite` with no `@media (prefers-reduced-motion: reduce)` block in the stylesheet at all.

Why it matters

Users with vestibular disorders who have set the OS-level reduce-motion preference still get these looping animations at full strength, which is a direct accessibility failure, not a stylistic nitpick.

Fix

Wrap infinite/looping keyframe animations in a prefers-reduced-motion query and fall back to a static or single-fade state.

@keyframes skeletonShimmer {
  100% { transform: translateX(100%); }
}
@media (prefers-reduced-motion: no-preference) {
  .skeleton-line::after { animation: skeletonShimmer 1.4s ease-in-out infinite; }
}
@keyframes skeletonShimmer {
  100% { transform: translateX(100%); }
}

Typography

No issues found

Spacing

No issues found

UX

No issues found

Craft

No issues found

Working well

  • The three-theme token architecture (dark default, light, oled) built entirely on CSS custom properties is a genuinely solid foundation: swapping `data-theme` recolors the whole app because nearly every component reads from `--bg-*`/`--text-*`/`--border-*` instead of hardcoding, which is exactly how theming should work.
  • Theme toggle and settings buttons (`#theme-toggle`, `#settings-btn`, and their mobile counterparts) all pair a `title` with an `aria-label`, giving both hover and assistive-tech users an identical, unambiguous name for icon-only controls. This is exactly how icon-only affordances should be labeled.
  • The shared hover treatment across `.nav-item`, `.filter-chip`, `.stat-card`, `.session-item`, and `.result-item` (consistent `border-color` + `background` shift, or a 1px lift) gives the app one coherent interaction language instead of a different hover idiom per component.
  • The `#cmdkBtn` search trigger is a real <button> with a visible "Search" label, a <kbd>⌘K</kbd> hint, and an aria-label. That combination tells sighted, keyboard, and screen-reader users the same thing three ways without adding visual clutter.

Scored July 22, 2026 with Rams Engine v0.0.2 · Engine changelog

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 this review on every PR.