calm-visual-parity

Validates Flutter screens against HTML-rendered design references using theme, colour token, and band-edge checks.

Updated Sep 2, 2026
One-click install
npx skills add https://github.com/zakariaf/Odova --skill calm-visual-parity-zakariaf
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: calm-visual-parity
Source: https://github.com/zakariaf/Odova/tree/main/.claude/skills/calm-visual-parity
Command: npx skills add https://github.com/zakariaf/Odova --skill calm-visual-parity-zakariaf

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes scripts (resource) and references (resource) components.

What problem does it solve? Flutter golden tests only prove a screen has not changed since its snapshot was taken; they cannot prove the screen ever matched the design. This Skill gates built Flutter screens against an independent design reference set (27 screens rendered from HTML/CSS in light/dark and LTR/RTL), catching design drift that goldens structurally cannot see. ## Core Features & Use Cases - Mechanical parity gates: Verifies the screen is in the requested theme, that every surface over 0.5% is within Δ24 of a Calm design token, and that at least 75% of the reference's horizontal band edges appear in the app within 4px. - Four-configuration coverage: Each referenced screen is checked in light/dark and LTR/RTL, with real Persian RTL references using Jalali dates and Eastern Arabic numerals. - CI gate script: scripts/check_parity.sh walks captured screenshots, runs the comparison tool per screen, and fails the build on wrong theme, untokenised colours, or broken vertical rhythm. - Use Case: Before opening a PR that changes any referenced UI screen, run the parity tests, execute the check script, and open the generated side-by-side sheet to confirm the app matches the design rather than merely matching last week's build. ## Quick Start Run the parity tests with flutter test test/parity/, then execute bash scripts/check_parity.sh and review the side-by-side sheets it writes to design/reference/_parity/.

Frequently Asked Questions about calm-visual-parity

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I check a Flutter screen matches its design reference?

Capture the screen at 390x844 @2x in a widget test using the pumpApp harness, then run node tools/compare_to_reference.mjs with the screen id, theme, and direction. The tool gates theme, colour tokens, and horizontal band edges, and writes a side-by-side sheet for human review.

What is the difference between Flutter golden tests and visual parity checks?

Golden tests compare a widget against a PNG generated from that same widget, so they catch regressions but not design drift. Parity checks compare the app against references rendered independently from the design system in Chrome, proving the screen matches what was designed.

Why does the parity check not use a raw pixel diff?

The reference is Chrome rendering HTML/CSS while the app is Skia, so glyph rasterisation, shadows, and gradients differ permanently; 25-45% of pixels differ on a correct screen. Instead it gates theme, colour against the token list, and vertical band edges, which survive the renderer difference.

Why does the parity check fail with a wrong theme error?

The wrong-theme failure means the largest surface colour belongs to the opposite palette, which is almost always a harness issue rather than the screen. Pin ThemeMode explicitly in the widget test instead of relying on platform brightness.

Can I compare app colours directly against the reference PNG pixels?

No. The committed reference PNGs are palette-quantised, so exact token hexes do not survive in them. Colour is compared app-versus-token-list from design/calm/odova.css with a Δ24 tolerance that absorbs the quantisation.

When should the design reference set be regenerated?

Regenerate only after a deliberate design change, in the same PR, by editing design/calm/odova.css, rebuilding screens.html, re-shooting, and re-optimising. Regenerating to clear an unintended failure deletes the record of what was designed.