Parity audit

QA

Component-by-component parity of the unified-design port against this library. One independent owner agent audited each component across ten checks; every claim below carries file-and-line evidence.

57
Components
201
Findings
6
High
128
Corrections
1
Clean

System-wide

8 high

These cut across the whole port, so each owner agent was told to treat them as known context rather than re-file them on all 57 components. They are the largest problems in the audit and the right place to start — most of the per-component noise resolves once these land.

D1

Web app pins Tailwind 3.3.2 while the port is written in 3.4 syntax

259 selectors compile to nothing on web — every has-[…] / group-has, size-*, the extended min-h / min-w / max-w steps, and text-balance / pretty / wrap. Proven by compiling unified-design under both versions and diffing emitted selectors (114,652 B vs 124,365 B). This is the root cause of the input-group textarea collapsing to a vertical letter column and the command palette shortcut floating mid-row.

Fix apps/next/package.json → "tailwindcss": "^3.4.17" (matches the expo workspace). Heals 18 components with no component edits.

F9

The design system typeface was never ported — everything renders in Mona Sans

The library loads Geist and Geist Mono via next/font and binds --font-sans / --font-mono / --font-heading. The port declares no font-family at all, and the product forces Mona Sans globally with a `html, body, *` rule — a universal selector, so any inheritance-based fix silently loses. Type sizes and tracking were tuned for Geist's metrics, so the whole type system reads wrong even where the numbers match.

Fix Load Geist in _app, bind the font tokens, then apply on .unified-design AND every portalled data-slot surface plus their descendants (portals mount outside the scope).

F4

Bare text-* classes compile 1–14px smaller than the library intends

The product's Tailwind config overrides the fontSize scale: text-sm renders 13px (library 14), base 14 (16), lg 15 (18), xl 16 (20), 2xl 18 (24). Roughly 70 sites across 35 files kept the library's class names and silently shrank. text-xs is 12px on both sides and is safe.

Fix Swap every bare text-* at sm and above for an arbitrary value (text-[14px], text-[16px] leading-6, …).

F7

Form focus rings fragmented into five treatments

The library has exactly two: fields carry an opaque --ring-soft halo (#b7d6ff), actions carry ring/50. The port has 25% color-mix on eleven atoms, 30% on the filter rail, 50% where correct, a 2px-wide ring on calendar, and no ring at all on input-group and the OTP group (those rules are D1-dead). A mix composites differently on every surface; the token does not.

Fix Add --ring-soft, replace the ~20 color-mix sites, fix calendar's width, and bump Tailwind so group-level rings compile.

F6

Entrance motion gutted on every floating surface

The library fades and zooms overlays in over 100ms with per-side slide. The port contains a single animate-in across all 58 files; the dialog overlay is reduced to an opacity flip. Root cause: the repo has no tailwindcss-animate. Every dialog, tooltip, popover and menu pops on frame one.

Fix Add the plugin, then restore the library motion strings on the ten overlay surfaces.

F2

Control-height scale shifted one step, xs and lg missing

--control-h-sm and -md hold 28px and 32px where the library sets 24 and 28 — so the token that guarantees a Button and an Input are the same height is off by one step. The filter rail consumes these tokens directly and renders every control 4px too tall.

Fix Restore xs 20 / sm 24 / md 28 / lg 32; the rail heals with no component edit.

F3

Solid tone CTAs sit 1–2 ramp steps too light and fail contrast

The library anchors its solid triads deliberately below the 500 step so white labels clear AA — info and success and error at 600, warning at 700. The port maps every tone to the plain 500 token: warning reaches roughly 2.9:1 with white, info 3.3:1, success 3.9:1.

Fix Add the *-solid / *-on-solid token group and repoint TONE_SOLID at it.

F1

Disabled text and icons are effectively invisible

--text-disabled and --icon-disabled point at neutral-200 (#e5e5e5), roughly 1.15:1 against the page. The library uses neutral-400 (#a1a1a1, about 2.4:1) and its source comment says disabled must stay legible.

Fix Point both at --neutral-400.

M5

Dark theme not ported

The library remaps 68 semantic tokens under .dark; the port has no dark block. Several atoms still carry dark: classes that now reference nothing, and a few value-equal shortcuts (tooltip surface via --foreground, avatar neutral via foreground/background) will invert when dark does ship.

Fix Port the dark semantic block, or decide explicitly that the port is light-only for now.

M1

Shadow recipes re-derived on a blue-tinted ink

--shadow-color is 15 15 18 (blue-cast) where the library uses a neutral 10 10 10, and the layer counts, offsets and opacities were rebuilt rather than ported. Four recipes are missing entirely — thumb, thumb-lg, well and highlight — so consumers inlined approximations; the filter tree's checkbox well lost its inset and now reads raised instead of recessed.

Fix Replace depth.css with the library recipes on neutral ink and add the four missing tokens.

M6

Seven components never ported

activity-feed, agency-card, breadcrumb, list-card, pagination, and the direction/RTL helper have no port. Button also carries in-group styles for a ButtonGroup that does exist, and there is no barrel export, so the single-import-surface rule the library enforces has no equivalent here.

Fix Port the missing set and add an index barrel with a lint rule against deep imports.