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

huntabyte/shadcn-svelte

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

30 files reviewed·August 1, 2026

View on GitHub

Low

Design risk in this codebase.

9issues
Serious & Moderate · top 6 shown below

Verdict

This block viewer is functionally solid and clearly uses shared context well, but the toolbar and tree components lean hard on arbitrary Tailwind escape hatches (data-slot attribute selectors, hand-tuned indentation multipliers, raw hex gradients) instead of the primitives' own APIs, which will make future theme or size changes fragile. The recurring touch-target shortfall across the toggle group and resize handle suggests touch use wasn't tested against this toolbar's tight 32px height. Nothing here is broken outright, but the accumulation of one-off styling is the kind of debt that compounds fast in a component this reused.

Files Rams reviewed

docs/src/lib/components/block-viewer-code.svelte

docs/src/lib/components/block-viewer-toolbar.svelte

docs/src/lib/components/block-viewer-tree.svelte

docs/src/lib/components/block-viewer-view-mobile.svelte

docs/src/lib/components/block-viewer-view.svelte

docs/src/lib/components/block-viewer.svelte

docs/src/lib/components/blocks-nav.svelte

docs/src/lib/components/cards/activity-goal.svelte

docs/src/lib/components/cards/appearance-settings.svelte

docs/src/lib/components/cards/cards-demo.svelte

docs/src/lib/components/cards/chat.svelte

docs/src/lib/components/cards/create-account.svelte

docs/src/lib/components/cards/demo.svelte

docs/src/lib/components/cards/exercise-minutes.svelte

docs/src/lib/components/cards/field-hear.svelte

docs/src/lib/components/cards/forms.svelte

docs/src/lib/components/cards/input-demo.svelte

docs/src/lib/components/cards/input-group-button-demo.svelte

docs/src/lib/components/cards/item-demo.svelte

docs/src/lib/components/cards/notion-prompt-form.svelte

docs/src/lib/components/cards/payments-actions-cell.svelte

docs/src/lib/components/cards/payments.svelte

docs/src/lib/components/cards/report-issue.svelte

docs/src/lib/components/cards/root-components.svelte

docs/src/lib/components/cards/share.svelte

docs/src/lib/components/cards/stats.svelte

docs/src/lib/components/cards/team-members.svelte

docs/src/lib/components/chart-code-viewer.svelte

docs/src/lib/components/chart-copy-button.svelte

docs/src/lib/components/chart-toolbar.svelte

96/100

Accessibility

2 serious
AccessibilitySerious

docs/src/lib/components/block-viewer-toolbar.svelte:60

Desktop/Tablet/Mobile toggle and toolbar icons sit under touch target minimum

The ToggleGroup.Root wrapping the "Desktop", "Tablet", and "Mobile" items forces every child to `!size-6` (24px) inside an `h-8` (32px) container, and the adjacent "Open in New Tab" and "Refresh Preview" buttons use the same `size-6` class. All five controls sit in a single row with no room to grow inside the current 32px bar.

Why it matters

Touch targets under ~44px raise mis-tap rates on mobile and tablet, and this toolbar is the primary way to switch preview breakpoints, so a fumbled tap sends users to the wrong viewport.

Fix

Raise interactive icon controls to at least a 36-40px hit area, expanding the toolbar height if needed to fit real touch targets.

class="gap-1 *:data-[slot=toggle-group-item]:!size-6 *:data-[slot=toggle-group-item]:!rounded-sm"
class="gap-1 *:data-[slot=toggle-group-item]:!size-9 *:data-[slot=toggle-group-item]:!rounded-sm"
AccessibilitySerious

docs/src/lib/components/block-viewer-view.svelte:29

Resizable panel drag handle hit area falls well below touch target minimum

`Resizable.Handle` sets `w-3` (12px) with an inner `after:h-8 after:w-[6px]` (6px wide, 32px tall) grip that only widens to `after:h-10` on hover, leaving the actual draggable strip at 12px wide by default.

Why it matters

A drag handle this narrow is hard to grab precisely on touch devices, and pointer users on a trackpad have a small margin for error before missing the resize gesture entirely.

Fix

Increase the invisible hit area (the transparent `w-3` wrapper) to at least 44px while keeping the visible grip line thin.

class="relative z-20 hidden w-3 bg-transparent p-0 after:absolute after:end-0 after:top-1/2 after:h-8 after:w-[6px] after:-translate-x-px after:-translate-y-1/2 after:rounded-full after:bg-border after:transition-all after:hover:h-10 md:block"
class="relative z-20 hidden w-11 bg-transparent p-0 after:absolute after:end-0 after:top-1/2 after:h-8 after:w-[6px] after:-translate-x-px after:-translate-y-1/2 after:rounded-full after:bg-border after:transition-all after:hover:h-10 md:block"
96/100

Spacing

2 serious
SpacingSerious

docs/src/lib/components/block-viewer-tree.svelte:46

Folder icon has no size class, breaking icon consistency with file rows

The file row uses `<FileIcon class="size-4" />`, but the folder row's `<FolderIcon />` has no size class at all, so folder icons render at their unstyled default size next to files sized to `size-4`.

Why it matters

Mismatched icon sizes between file and folder rows in the same tree component make the hierarchy look unfinished and disrupt the visual rhythm users rely on to scan a file list quickly.

Fix

Apply the same size utility to every icon at the same nesting level for visual consistency.

<FolderIcon />
<FolderIcon class="size-4" />
SpacingSerious

docs/src/lib/components/block-viewer-tree.svelte:19

File tree indentation uses hand-tuned per-index multipliers instead of a scale

`Sidebar.MenuButton` computes `--index: {index * (index === 2 ? 1.2 : 1.3)}rem` for files, and `Collapsible.Trigger` a few lines down uses a different `index === 1 ? 1 : 1.2` multiplier for folders. Two separate ad hoc formulas control the same visual property.

Why it matters

Indentation that isn't driven by one consistent step value drifts unpredictably as the tree gets deeper, so nested folders and files won't align cleanly against each other at every level.

Fix

Replace the special-cased multipliers with a single consistent step (e.g. index * 1rem) shared by both file and folder rows.

style="--index: {index * (index === 2 ? 1.2 : 1.3)}rem"
style="--index: {index * 1.25}rem"

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

Components

1 serious
Design SystemSerious

docs/src/lib/components/block-viewer-toolbar.svelte:37

Tabs.List sizes children via raw data-slot selectors instead of a variant

`Tabs.List` styles its `Tabs.Trigger` children with `*:data-[slot=tabs-trigger]:h-6`, `*:...rounded-sm`, `*:...px-2`, `*:...text-xs` instead of passing a size prop, and the same arbitrary-attribute pattern repeats for the `ToggleGroup.Root` a few lines below.

Why it matters

Reaching past the component API to restyle children through attribute selectors means any future change to the Tabs or ToggleGroup primitive silently breaks this toolbar, and the pattern has to be hand-copied everywhere it's needed, which raises maintenance cost.

Fix

Push a size variant into the shared Tabs/ToggleGroup primitives instead of overriding children through attribute selectors at each call site.

<Tabs.List
	class="grid h-8 grid-cols-2 items-center rounded-md p-1 *:data-[slot=tabs-trigger]:h-6 *:data-[slot=tabs-trigger]:rounded-sm *:data-[slot=tabs-trigger]:px-2 *:data-[slot=tabs-trigger]:text-xs"
>
<Tabs.List size="sm" class="grid h-8 grid-cols-2 items-center rounded-md p-1">
98/100

UX

1 serious
UXSerious

docs/src/lib/components/block-viewer-tree.svelte:37

Folder rows show a collapse chevron that can never actually collapse

`Collapsible.Root` for folder rows is hardcoded `open={true}` with no bound state and no `onOpenChange` handler, while the chevron carries `class="transition-transform"` and rotates via `[data-state=open]` styling, implying it can toggle.

Why it matters

A chevron and clickable trigger that visually promise expand/collapse but never respond leave users clicking a folder repeatedly expecting the tree to close, which wastes time and reads as a broken control in a code file browser.

Fix

Bind Collapsible.Root's open state to a variable the trigger can toggle, or remove the chevron affordance if folders are meant to always stay expanded.

<Collapsible.Root
	class="group/collapsible [&[data-state=open]>button>svg:first-child]:rotate-90"
	open={true}
>
<Collapsible.Root
	class="group/collapsible [&[data-state=open]>button>svg:first-child]:rotate-90"
	bind:open
>

Typography

No issues found

Color

No issues found

Motion

No issues found

Craft

No issues found

Working well

  • The 'Open in New Tab' and 'Refresh Preview' buttons in block-viewer-toolbar.svelte pair a visible icon with an explicit `<span class="sr-only">` label, giving both a real accessible name instead of leaning on the `title` attribute alone: a pattern the neighboring toggle group unfortunately doesn't follow.
  • block-viewer.svelte's use of a `BlockViewerContext` class with getters/setters instead of prop drilling keeps the toolbar, tree, view, and code panels in sync from one shared source of truth, which is the right call for a component with this many siblings reading the same state.
  • The responsive swap from `rounded-lg`/`aspect-[4/2.5]` to `md:rounded-xl`/`md:aspect-auto` in block-viewer-view.svelte shows the layout was actually tuned per breakpoint rather than shipped as one fixed shape for every screen size.

Scored August 1, 2026 with Rams Engine v0.0.3 · Engine changelog
First scored July 29, 2026: 87/100. This rescore on v0.0.3: 85/100.

This page is an automated design review of huntabyte/shadcn-svelte’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