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

theexperiencecompany/gaia

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

30 files reviewed·July 25, 2026

View on GitHub

Elevated

Design risk in this codebase.

4issues
Critical & Serious

Top fix

Make download actions visible and operable via keyboard, not just hover

See the fix

Verdict

A hover-only download control locks out keyboard users while a crash screen's recovery button quietly does nothing. The core risk is interaction affordances that look finished but fail under anything but a mouse and a happy path.

Files Rams reviewed

apps/web/src/app/[locale]/(landing)/brand/components/BrandAssets.tsx

apps/web/src/app/[locale]/(landing)/brand/components/BrandColors.tsx

apps/web/src/app/[locale]/(landing)/brand/components/DownloadAsset.tsx

apps/mobile/src/app/(app)/_layout.tsx

apps/mobile/src/app/_layout.tsx

apps/web/src/app/[locale]/(desktop)/desktop-popup/feed/page.tsx

apps/web/src/app/[locale]/(landing)/about/page.tsx

apps/web/src/app/[locale]/(landing)/ai-chief-of-staff/page.tsx

apps/web/src/app/[locale]/(landing)/alternative-to/[slug]/page.tsx

apps/web/src/app/[locale]/(landing)/alternative-to/page.tsx

apps/web/src/app/[locale]/(landing)/automate/[combo]/page.tsx

apps/web/src/app/[locale]/(landing)/automate/page.tsx

apps/web/src/app/[locale]/(landing)/blog/[slug]/page.tsx

apps/web/src/app/[locale]/(landing)/blog/page.tsx

apps/web/src/app/[locale]/(landing)/bots/page.tsx

apps/web/src/app/[locale]/(landing)/brand/page.tsx

apps/web/src/app/[locale]/(landing)/cli/page.tsx

apps/web/src/app/[locale]/(landing)/compare/[slug]/page.tsx

apps/web/src/app/[locale]/(landing)/compare/page.tsx

apps/web/src/app/[locale]/(landing)/contact/page.tsx

apps/web/src/app/[locale]/(landing)/desktop-login/page.tsx

apps/web/src/app/[locale]/(landing)/download/page.tsx

apps/web/src/app/[locale]/(landing)/faq/page.tsx

apps/web/src/app/[locale]/(landing)/features/[slug]/page.tsx

apps/web/src/app/[locale]/(landing)/for/page.tsx

apps/web/src/app/[locale]/(landing)/inbox-zero-ai/page.tsx

apps/web/src/app/[locale]/(landing)/learn/[term]/page.tsx

apps/web/src/app/[locale]/(landing)/learn/page.tsx

apps/web/src/app/[locale]/(landing)/login/page.tsx

apps/web/src/app/[locale]/(landing)/manifesto/page.tsx

95/100

Accessibility

1 critical1 serious
AccessibilityCritical

apps/web/src/app/[locale]/(landing)/brand/components/DownloadAsset.tsx:66

Download buttons only appear on mouse hover, locking out keyboard users

The download actions in DownloadAsset.tsx sit in a div at line 66-67 whose visibility is entirely controlled by isHovered, toggled by onMouseEnter/onMouseLeave on the parent wrapper (lines 48-49). There is no focus-within equivalent and no touch fallback, so the buttons stay at opacity-0 for anyone who tabs through the page or taps on mobile.

Why it matters

A keyboard user tabbing through the brand assets page can focus the hidden Button elements but never see them appear, and touch users get no hover event at all, so the entire download flow is unreachable for both groups.

Fix

Reveal interactive controls on focus-within as well as hover, and keep them accessible at low opacity on touch devices.

<div
  className="group relative"
  onMouseEnter={() => setIsHovered(true)}
  onMouseLeave={() => setIsHovered(false)}
>
  ...
  <div
    className={`absolute bottom-4 right-4 flex gap-2 transition-opacity duration-300 ${isHovered ? "opacity-100" : "opacity-0"}`}
  >
<div
  className="group relative"
  onMouseEnter={() => setIsHovered(true)}
  onMouseLeave={() => setIsHovered(false)}
  onFocus={() => setIsHovered(true)}
  onBlur={() => setIsHovered(false)}
>
  ...
  <div
    className="absolute bottom-4 right-4 flex gap-2 transition-opacity duration-300 opacity-0 group-hover:opacity-100 group-focus-within:opacity-100"
  >
AccessibilitySerious

apps/web/src/app/[locale]/(landing)/brand/components/DownloadAsset.tsx:70

Download icon has no aria-hidden, adding noise to screen reader output

Each download Button at line 70-79 renders startContent={<Download01Icon width={15} height={15} />} next to a visible text label like 'PNG' or 'PNG (dark)'. The icon has no aria-hidden attribute, so assistive tech may announce it as an unlabeled graphic alongside the format text.

Why it matters

Redundant icon announcements add clutter to every button a screen reader user hears, making the list of format options slower to parse than the visible label alone would be.

Fix

Mark decorative icons that sit beside visible text labels as aria-hidden so screen readers skip them.

startContent={<Download01Icon width={15} height={15} />}
startContent={<Download01Icon width={15} height={15} aria-hidden="true" />}
98/100

Color

1 serious
Design SystemSerious

apps/mobile/src/app/_layout.tsx:40

Raw hex #111111 duplicated across crash screen and root container

The CrashRecoveryFallback View (line 44) and the root GestureHandlerRootView (line 141) both hardcode style={{ backgroundColor: "#111111" }}, while the rest of the file uses Tailwind classes like bg-primary and text-white for color.

Why it matters

Two hardcoded literals for the same background mean a future theme or dark-mode adjustment requires editing raw hex in two places instead of one token, and it's easy for the values to drift apart over time.

Fix

Replace the raw hex literal with the same background token or Tailwind class used elsewhere in the file.

<View
  style={{ flex: 1, backgroundColor: "#111111" }}
  className="items-center justify-center p-8"
>
<View
  className="flex-1 items-center justify-center p-8 bg-background"
>

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/mobile/src/app/_layout.tsx:53

"Restart App" button does nothing to recover from the crash it names

In CrashRecoveryFallback, the Pressable labeled "Restart App" (lines 53-58) calls onPress={() => SplashScreen.preventAutoHideAsync()}. That call only tells the splash screen not to auto-hide; it does not reload the app, reset navigation, or reset the ErrorBoundary state.

Why it matters

A user who hits a crash and taps the only recovery action on screen gets no visible change, so they're stuck on the crash screen with no way forward except force-quitting the app themselves.

Fix

Wire the recovery button to an action that actually resets app state, such as the ErrorBoundary's reset callback or a hard reload.

<Pressable
  onPress={() => SplashScreen.preventAutoHideAsync()}
  className="bg-primary px-8 py-3 rounded-lg"
>
  <Text className="text-white font-semibold">Restart App</Text>
</Pressable>
<Pressable
  onPress={() => resetErrorBoundary?.()}
  className="bg-primary px-8 py-3 rounded-lg"
>
  <Text className="text-white font-semibold">Restart App</Text>
</Pressable>

Typography

No issues found

Spacing

No issues found

Components

No issues found

Motion

No issues found

Craft

No issues found

Working well

  • Wrapping the whole tree in ErrorBoundary with a dedicated CrashRecoveryFallback is a resilience pattern most React Native apps skip entirely, giving users a defined screen instead of a blank crash.
  • Button labels dynamically include the variant, e.g. 'PNG (dark)', so users know exactly which asset variant they're about to download before they click.

Scored July 25, 2026 with Rams Engine v0.0.3 · Engine changelog
First scored July 23, 2026: 59/100. This rescore on v0.0.3: 59/100.

This page is an automated design review of theexperiencecompany/gaia’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; 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.

Or get a design review on every pull requestInstall Rams