design-visual-parity
Proves built screens match approved design references (iOS, Android, light/dark, RTL) per element.
Skill by zakariaf
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/zakariaf-design-visual-parity
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: design
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 26, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
- Runs as
- Node.js package
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/design-visual-parity/usr/libexec/java_home- Your home directory (~)
What's inside
- Skill name
design-visual-parity- Description
- Proves built screens match approved design references (iOS, Android, light/dark, RTL) per element. Use when a screen is built or changed, or for visual parity, design match, screenshot compare. Not for building screens (screen-contracts).
- License
- MIT
- Instructions
- 259 lines in SKILL.md · view on GitHub
Before installing
- Ships executable scripts
Files (157)
- SKILL.md
- shared.json · assets/
- create-root-kits-parity.ts · examples/
- model-opener.ts · examples/
- parity-launch-screen.tsx · examples/
- parity-route.tsx · examples/
- screens.json · examples/
- test-only-entry-additions.ts · examples/
- worked-loop.md · examples/
- contract-format.md · references/
- devices-and-capture.md · references/
- failure-messages.md · references/
- mockup-and-references.md · references/
- parity-harness.md · references/
- signoff-and-waivers.md · references/
- what-exact-means.md · references/
- capture-app.mjs · scripts/
- check-harness.mjs · scripts/
- check-lib.mjs · scripts/
- check-mockup.mjs · scripts/
- check-parity.mjs · scripts/
- check-signoff.mjs · scripts/
- app-modules.mjs · scripts/lib/
- contract.mjs · scripts/lib/
- deps.mjs · scripts/lib/
- gates.mjs · scripts/lib/
- hierarchy.mjs · scripts/lib/
- images.mjs · scripts/lib/
- mockup-html.mjs · scripts/lib/
- pixel-diff.mjs · scripts/lib/
- reference-changes.mjs · scripts/lib/
- render.mjs · scripts/lib/
- runs.mjs · scripts/lib/
- scene.mjs · scripts/lib/
- source-scan.mjs · scripts/lib/
- tools.mjs · scripts/lib/
- ts-literal.mjs · scripts/lib/
- make-sheet.mjs · scripts/
- package-lock.json · scripts/
- package.json · scripts/
- run-parity.mjs · scripts/
- selftest.mjs · scripts/
- setup-parity-device.mjs · scripts/
- shoot-design.mjs · scripts/
- visual-parity.json · templates/contracts/
- visual-parity.schema.json · templates/contracts/
- android-parity.json · templates/design/parity/devices/
- iphone-16-pro.json · templates/design/parity/devices/
- fixture.json · templates/design/parity/
- index.html · templates/design/parity/mockup/
- signoff.json · templates/design/parity/
- waivers.json · templates/design/parity/
- parity-error-screen.tsx · templates/src/features/parity/
- parity-fixture.json · templates/src/features/parity/
- parity-fixture.test.ts · templates/src/features/parity/
- parity-fixture.ts · templates/src/features/parity/
- parity-frame-root.test.tsx · templates/src/features/parity/
- parity-frame-root.tsx · templates/src/features/parity/
- parity-launch-bridge.test.tsx · templates/src/features/parity/
- parity-launch-bridge.tsx · templates/src/features/parity/
- …and 97 more
SKILL.md (first lines)
# Design visual parity
Makes one rule true: every built screen is compared with its approved design reference on every
device, theme and language of the app, and fixed until it matches. Machines check geometry, text,
colour, borders, type and shape per element; the agent checks the rest by looking at side-by-side
sheets; `check-signoff.mjs` proves both happened for the current build and writes the summary a report's
"Design match" line names.
## Rules that must hold
1. **No screen is done until every run of the done set passes**: each design frame on every device of
the contract (an iOS simulator and an Android emulator by default), in light and dark, in every
language the app ships (its RTL one included), at every scroll offset `run-parity.mjs` plans for a
tall frame, against the reference the app's facts pick. Narrowing is for iteration: a narrowed check
prints `narrowed: not a sign-off` and fails. Why: dark mode and right to left are where screens
break; one passing variant proves little. (`narrowed`, `not-captured`, `coverage`)
2. **The committed references are the authority.** They change only after the reviewer approved a
design change, logged first in the manifest's `referenceChanges`, rendered with
`shoot-design.mjs --update-reference --change <id>`; never to make a screen pass, and a change is
never a waiver. Why: a reference edited to match the app turns the check into a mirror.
(`reference-change-unlogged`, `reference-drift`, `stale-reference`)
3. **The app's facts pick the reference; nobody guesses.** A frame that depends on what the app has
gets design-derived variants (contract `facts`, `variants`), composed when several match; a fact left
out stops every script; a variant is derived from the rendered mockup, never drawn by hand. Why: a
missing element that only another fact has is a wrong reference, not a waiver.
(`reference-variant`, `variant-derive`, `contract-invalid`)
4. **Never widen a tolerance, add a mask or skip a gate to get a pass.** Every number is a measured
noise floor; type-role floors need their probe evidence and stay at or under 3 pt. What the platform
truly cannot draw gets a waiver: one element, one rule, its class (`platform`,
`platform-text-shaping` naming the glyphs, `design-artefact` quoting the mockup CSS), the reason,
the date the reviewer was told. Why: a widened number hides every future defect of that size.
(`waiver-invalid`)
5. **Capture the real app with `capture-app.mjs` on this session's own named device**: a Release build
of a development or preview variant, launched straight into the frame (iOS: the `-parity` launch
argument, never `simctl openurl`; Android: the parity link sent to the named package). Every call
names its device (a UDID, `adb -s <serial>`, Maestro `--device` and this run's own driver port
before the command, on both platforms), and every launch carries a nonce the hierarchy dump must contain. Why: a dump
once came from another session's simulator; a Debug build, a deep link alert or a hand-made
screenshot compares nothing. (`system-alert`, `unstable`, `changed-during-capture`, `not-a-capture`)
6. **Machine gates first, then the look.** `check-parity.mjs` must pass, then every sheet image is read
and the seven eye checks and every difference go into the ledger for exactly that sheet. Why: the
gates have tolerances; icons, pictures, shadow feel, wrapping and mirroring need eyes.
(`not-looked`, `eye-check-open`, `difference-open`, `looked-at-old-sheet`, `stale-sheet`)
7. **Fix the app one gate at a time, in the printed order** (reached, scroll, missing, bounds, text,
fill, border, text-ink, structure); read the element's crop before changing code; stop and report
after three failed fixes of the same failure. Why: a wrong padding moves everything below it.
8. **testIDs exactly as the screen contract says, on the accessible element; bounds only for what
Maestro can list.** Parts inside an accessible element (`parent`) and decoration hidden from screen
readers (`a11yHidden`) are crop-only, judged in their `coveredBy` ancestor's aligned crop, never
`missing`; never un-hide decoration to measure it. Why: Maestro reads the accessibility tree.
(`element-reach`, `element-cover`, `missing`)
9. **The harness is the shipped templates, test-only.** One strict launch parser (an error screen on
bad input, never a silent fallback), the consent moment held (in an app with ads only an
`ADS_MODE=off` build launches), every test-build switch set on every launch, the design's
fixture written unchanged through the app's repositories, each frame state opened by its owning
model's `useFrameStateOpener` through the handler a press uses, motion held still through the one
reduce-motion path, reached only through the test-only gate, the launch marker in every modal root
as the first child of its `accessibilityViewIsModal` view (the shared Scrim and ConfirmDialog
included), no capture-only branch (`harness-capture-branch`).
Why: a hand-written harness kept stale state across frames and drew things the screen never would.
(`harness-*`, check-harness.mjs)
10. **The mockup is static, offline and marked.** One `data-frame` per design frame, one `data-testid`
per element of the frame and no unknown ones, fonts from the exact files the app bundles. Why: both
sides must rasterise the same outlines, and a mockup that disagrees with the contract renders
references nobody can match. (`mockup-*`, `fonts`, `design-text`)
11. **Pixel identity is never promised.** Anti-aliasing, 1/3 pt rounding and each type role's measured
glyph offset always differ; the whole-screen difference is printed for information and never
decides. Why: correct builds scored 0.13-0.51 %, overlapping real defects.
12. **The waivers, references (with the manifest), fixture, mockup and device profiles are gated
paths, the sign-off ledger is not; the summary backs the report.** A commit that changes a gated
one carries a `Gate-Change:` trailer; a report's Design match line names
`reports/parity/summary.json`. Why: what the gate accepts changes only on purpose and in sight.
(`gated-paths`)
## Workflow
1. **Look first.** From the app root run `node ${CLAUDE_SKILL_DIR}/scripts/check-mockup.mjs .` and
`node ${CLAUDE_SKILL_DIR}/scripts/check-harness.mjs .`. NOT APPLICABLE means the app keeps no parity
contract yet: step 2. Read [references/contract-format.md](references/contract-format.md) once.
2. **The contract and the mockup, once per app.** Copy `templates/contracts/visual-parity.json` (+
schema) to `contracts/`, `templates/design/parity/` to `design/parity/` (device profiles, empty
waivers and ledger, the fixture, the demo mockup), and give each design frame's screen-contract state
its `"reference": "<frame>.png"` (screen-contracts; [examples/screens.json](examples/screens.json)
shows the shape; step 3 writes the image it names). Draw or port the approved design into the mockup
following [references/mockup-and-references.md](references/mockup-and-references.md); run
`check-mockup.mjs .` until `RESULT: PASS`.
3. **The references, once per approved design.** Install the pinned Playwright once (`npm ci --prefix
${CLAUDE_SKILL_DIR}/scripts`, or into `.skill-tooling/design-visual-parity` with `--tooling` when the
skill folder is read-only or shared). The first render of an approved design: `node
${CLAUDE_SKILL_DIR}/scripts/shoot-design.mjs . --update-reference` (it also writes the screen
contract's `<frame>.png`); later ones only after logging the change (`--change <id>`); prove them
with `shoot-design.mjs . --check`. The reviewer looks at the
renders and approves them.
4. **The harness, once per app.** Read [references/parity-harness.md](references/parity-harness.md).
Copy `templates/src/features/parity/` (the parity kit `parity-root-kit.tsx` included),
`templates/src/hooks/use-frame-request.tsx`, `use-frame-state-opener.ts` and
`use-frame-scroll-target.ts`, and `templates/src/ui/parity-launch-marker.tsx` (each with its
test); export `createParityKit` and the app's launch screen from the test-only entry
([examples/test-only-entry-additions.ts](examples/test-only-entry-additions.ts)), register the kit
in the app's root-kit registry among the test build's kits
([examples/create-root-kits-parity.ts](examples/create-root-kits-parity.ts): the root skeleton stays
unchanged) and add the launch route ([examples/parity-route.tsx](examples/parity-route.tsx)); build
the appliers, `consent` included; open each planned frame state in its model; add the marker to the
shared modal roots; register the launch route in `contracts/navigation.json` (`routes`,
`debugRoutes`) and `contracts/screens.json` (`ignoredRoutes`); keep `.parity/` git-ignored and the
parity paths gated (both in the canonical `.gitignore` and `quality-gates.json`; rule 12: listed one
by one, never `design/parity/**`, plus `design/parity/<device>/**` for a device beyond the two
defaults). Run the harness tests (`npx jest src/features/parity src/hooks/use-frame
src/ui/parity-launch-marker.test.tsx --ci --maxWorkers=2`), then `check-harness.mjs .` until it
passes. Before the first approved design, `contracts/visual-parity.json` may plan no frame
(`"frames": {}` and no screen state with a `reference`): check-harness still proves the wiring and
the frame scripts print NOT APPLICABLE.
5. **Before building or changing a screen,** open its references (light and dark RTL first), the
frame's elements (screen-contracts' `list-screen.mjs`) and the frame kind and masks in the contract.
6. **The device, once per session.** `node ${CLAUDE_SKILL_DIR}/scripts/setup-parity-device.mjs .
--device iphone-16-pro --appearance light --name <project>-parity-<key>` (and the same for
`android-parity`); it prints the UDID or serial. Build and install the Release build of the preview
variant on it (ios-simulator-build, android-emulator-build). Read
[references/devices-and-capture.md](references/devices-and-capture.md) when anything fails.From zakariaf/ReactNative-Skills, MIT.
More from zakariaf/ReactNative-Skills
- 0.606score
debug-menu-and-test-hooks
zakariaf
Gates test-only code behind one literal TEST_ONLY switch: debug menu, debug link, simulated clock and offline.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
accessibility-as-code
zakariaf
Enforces a11y labels, 44pt targets, 200% text, VoiceOver, TalkBack.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
adaptive-layout
zakariaf
Lays screens out by window, not device: breakpoints, master-detail panes, readable widths, grids.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
admob-ads-and-consent
zakariaf
Builds AdMob ads behind a port - banners, interstitials, rewarded, UMP consent then ATT, pacing, ADS_MODE test IDs.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
analytics-and-consent
zakariaf
Gates analytics on opt-in consent: no SDK before a yes, typed events without personal data, ATT.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
android-release-play
zakariaf
Ships Android App Bundles to Google Play: upload key, Play App Signing, AAB gate, versionCode, tracks, rollout.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
architecture-and-boundaries
zakariaf
Places app code in the src/ layout and checks import boundaries: one-way zones, pure core, ports with fakes, one composition root.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
async-safety
zakariaf
Prevents silent async bugs: effect races, stale results, lost promises, leaked listeners and timers, AbortSignal gaps.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
audio-and-haptics-feedback
zakariaf
Builds SFX and haptics behind ports.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
auth-and-secure-storage
zakariaf
Builds sign-in - tokens in expo-secure-store, shared refresh, protected routes, OAuth PKCE, Apple sign-in.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
background-tasks
zakariaf
Builds expo-background-task jobs: idempotent, budgeted runs.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
canvas-gestures-and-hit-testing
zakariaf
Turns canvas taps, swipes, drags and aim into typed intents: one gesture module, hit-testing on the drawn layout.
SkillAFreshness: A★ 11Claude Code +9
Signals
- Stars
- 11
- Forks
- 2
- Open issues
- 0
- Last commit (this folder)
- Oct 17, 2026 (12 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/zakariaf/ReactNative-Skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from zakariaf
- 0.606score
admob-ads-and-consent
zakariaf
Builds AdMob ads behind a port - banners, interstitials, rewarded, UMP consent then ATT, pacing, ADS_MODE test IDs.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
accessibility-as-code
zakariaf
Enforces a11y labels, 44pt targets, 200% text, VoiceOver, TalkBack.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
canvas-gestures-and-hit-testing
zakariaf
Turns canvas taps, swipes, drags and aim into typed intents: one gesture module, hit-testing on the drawn layout.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
adaptive-layout
zakariaf
Lays screens out by window, not device: breakpoints, master-detail panes, readable widths, grids.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
debug-menu-and-test-hooks
zakariaf
Gates test-only code behind one literal TEST_ONLY switch: debug menu, debug link, simulated clock and offline.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
analytics-and-consent
zakariaf
Gates analytics on opt-in consent: no SDK before a yes, typed events without personal data, ATT.
SkillAFreshness: A★ 11Claude Code +9
Cite this page
design-visual-parity skill. Agent Mart. https://agentmart.dev/skills/zakariaf-design-visual-parity (last updated 2026-10-24)